在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']
谢谢! :)
答案 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的方式。
答案 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]); }
}