Javascript中的Itertools.combinations

时间:2017-08-22 09:11:24

标签: javascript

在JavaScript中是否有与Python的itertools类似的库?我特别感兴趣的是排列和组合。

我没有使用Node.js.

我想做这样的事情:

array = ['a', 'b', 'c', 'd'];

//return non-duplicate combinations of length 2
['a', 'b']
['a', 'c']
['a', 'd']
['b', 'c']
['b', 'd']
['c', 'd']

谢谢! :)

4 个答案:

答案 0 :(得分:4)

您可以使用递归方法来获取具有指定大小的给定数组的排列。

MwWcfLibrary.PublicState.Interfaces.IPublicState
function getPermutations(array, size) {

    function p(t, i) {
        if (t.length === size) {
            result.push(t);
            return;
        }
        if (i + 1 > array.length) {
            return;
        }
        p(t.concat(array[i]), i + 1);
        p(t, i + 1);
    }

    var result = [];
    p([], 0);
    return result;
}

var array = ['a', 'b', 'c', 'd'];

console.log(getPermutations(array, 2));

答案 1 :(得分:3)

你可以使用我的es-iter库,它几乎是Python的itertools的一对一端口,但是以JS的方式。

https://github.com/abozhilov/ES-Iter#combinationsr

答案 2 :(得分:0)

对于笛卡儿产品,您可能需要查看利用lodash的{​​{3}}详细示例。该功能类似于Python中的this

答案 3 :(得分:0)

我喜欢itertools.combinations,并希望使用内存效率高的JavaScript generator function,但无法快速找到可接受的库,所以我自己开发了一个库。

它在TypeScript中(以帮助我跟踪簿记),但是我将在底部附加转译的JavaScript。

function* range(start: number, end: number) {
  for (; start <= end; ++start) { yield start; }
}

function last<T>(arr: T[]) { return arr[arr.length - 1]; }

function* numericCombinations(n: number, r: number, loc: number[] = []): IterableIterator<number[]> {
  const idx = loc.length;
  if (idx === r) {
    yield loc;
    return;
  }
  for (let next of range(idx ? last(loc) + 1 : 0, n - r + idx)) { yield* numericCombinations(n, r, loc.concat(next)); }
}

function* combinations<T>(arr: T[], r: number) {
  for (let idxs of numericCombinations(arr.length, r)) { yield idxs.map(i => arr[i]); }
}

所有黑魔法都在numericCombinations函数中,该函数是递归生成器-请参见yield*上的MDN文档。实际的combinations函数只是将其包装以匹配Python API。

我可以将其放在.ts文件中,并将其放在它的底部:

if (module === require.main) {
  const shorts = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
  let i = 0;
  for (let o of combinations(shorts, 7)) { i++; }
  console.log(i);
}

,Node在我的2015年老式笔记本电脑上用不到2.5分钟的时间即可打印出133784560,且内存使用量最少。也就是说,它产生了全部<三千四百万种方式,您可以从标准的52张纸牌中选择7张纸牌(即,所有完整的德州扑克手),而不会增加存储负担或过多负担-嵌套递归函数调用。

(Python3可以在20秒内完成此操作,或快7倍,加快上述欢迎的速度。)


JavaScript代码:

function* range(start, end) {
  for (; start <= end; ++start) { yield start; }
}
function last(arr) { return arr[arr.length - 1]; }
function* numericCombinations(n, r, loc = []) {
  const idx = loc.length;
  if (idx === r) {
    yield loc;
    return;
  }
  for (let next of range(idx ? last(loc) + 1 : 0, n - r + idx)) { yield* numericCombinations(n, r, loc.concat(next)); }
}
function* combinations(arr, r) {
  for (let idxs of numericCombinations(arr.length, r)) { yield idxs.map(i => arr[i]); }
}
相关问题