我在javascript中给出了一系列条目,例如:
var entries = ["cat", "dog", "chicken", "pig"];
我现在想迭代它们的所有独特的成对组合。在这个例子中,我想看看:
("cat", "dog"),
("cat", "chicken"),
...
在其他语言中,如scala,这非常简单。你刚才做了
entries.combinations(2)
javascript库中有类似的方法或功能吗?或者我只需要用嵌套循环以丑陋的方式自己编写它?
答案 0 :(得分:5)
var arr = ["cat","dog","chicken","pig"].map(function(item,i,arr) {
return arr.map(function(_item) { if( item != _item) return [item, _item];});
});
这将返回预期结果。有一些警告,它在没有垫片的旧浏览器中不起作用。
此外,重复的值是“未定义的”'而不是有4个3的数组。我确信有一个更优雅的方式来处理它。
这将为您提供正确的成对组合。
var arr = ["cat","dog","chicken","pig"].map(function(item,i,arr) {
var tmp = arr.map(function(_item) { if( item != _item) return [item, _item];});
return tmp.splice(tmp.indexOf(undefined),1), tmp;
});
这是相同代码的更易读的版本。
var myArray = ["cat", "dog", "chicken", "pig"];
var pairwise = myArray.map(function(item, index, originalArray) {
var tmp = originalArray.map(function(_item) {
if (item != _item) {
return [item, _item];
}
});
tmp.splice(tmp.indexOf(undefined), 1); // because there is now one undefined index we must remove it.
return tmp;
});
答案 1 :(得分:2)
据我所知。我认为你必须坚持使用嵌套循环。
这里也提出了类似的问题:Output each combination of an array of numbers with javascript也许你可以在那里找到答案。
答案 2 :(得分:1)
在回顾问题后,这个答案没有正确解决问题。该问题要求所有组合,但下面的函数组合了数组的所有相邻的偶数和奇数索引。
这是我使用reduce
进行的成对实现function pairwise(arr) {
return arr.reduce(function(acc, current, index) {
var isFirstPair = (index % 2) === 0;
if (isFirstPair) {
acc.push([current]);
} else {
lastElement = acc[acc.length - 1];
lastElement.push(current);
}
return acc;
}, []);
};
var nums = [1,2,3,4,5,6];
var res = pairwise(nums);
res.forEach(function(elem) {
console.log(elem);
});
返回:
[
[1, 2]
[3, 4]
[5, 6]
]
答案 3 :(得分:0)
使用ES6语法,可以使用@rlemon's answer的较短版本:
["cat","dog","chicken","pig"].sort().reduce(
(acc, item, i, arr) => acc.concat(
arr.slice(i + 1).map(_item => [item, _item])
),
[])
这会处理undefined
s,并且根据OP的问题也只会输出唯一组合。
答案 4 :(得分:0)
这是一个通用的TypeScript实现(您可以通过删除类型来获得纯JS):
// Returns an array of size
const sizedArray = (n: number): null[] => Array(n).fill(null);
// calls the callback n times
const times = (n: number, cb: () => void): void => {
while (0 < n--) {
cb();
}
};
// Fills up the array with the return values of subsequent calls of cb
const fillWithCb = <T>(n: number, cb: () => T): T[] => sizedArray(n).map(cb);
// Generic to produce pairwise, 3 element wise etc..
const nWise = (n: number): (<T>(array: T[]) => T[][]) => <T>(
array: T[]
): T[][] => {
const iterators = fillWithCb(n, () => array[Symbol.iterator]());
iterators.forEach((it, index) => times(index, () => it.next()));
return fillWithCb(array.length - n + 1, () =>
iterators.map(it => it.next().value)
);
};
// curried nWise with 2 -> pairWise
export const pairWise = nWise(2);
答案 5 :(得分:0)
最有效,最简单的解决方案可以减少和削减。但是,如果您只想获取值。您可以使用发电机。
// Util class
function pairWise(arr) {
return {
[Symbol.iterator]: function *() {
for(let i =0; i< arr.length; i= i+2)
yield arr.slice(i, i+2)
}
}
}
// How to use it
for(ent of pairWise([1,2,3,4,5,6, 7])){
console.log(ent)
}
// Output
/*
[ 1, 2 ]
[ 3, 4 ]
[ 5, 6 ]
[ 7 ]
*/