javascript数组中条目的成对组合
Posted
技术标签:
【中文标题】javascript数组中条目的成对组合【英文标题】:Pairwise combinations of entries in a javascript array 【发布时间】:2012-08-19 17:06:00 【问题描述】:我在 javascript 中获得了一组条目,例如:
var entries = ["cat", "dog", "chicken", "pig"];
我现在想遍历它们的所有独特的成对组合。在这个例子中,我想看看:
("cat", "dog"),
("cat", "chicken"),
...
在其他语言中,比如 scala,这非常简单。你只是这样做
entries.combinations(2)
javascript 库中是否有类似的方法或函数?还是我只需要自己用嵌套循环的丑陋方式编写它?
【问题讨论】:
是的,你必须自己写。 【参考方案1】:var arr = ["cat","dog","chicken","pig"].map(function(item,i,arr)
return arr.map(function(_item) if( item != _item) return [item, _item];);
);
这将返回预期的结果。需要注意的是,它在没有 shims 的旧浏览器中不起作用。
此外,重复值是“未定义”,而不是 4 个 3 个数组。我相信有一种更优雅的方式来处理这个问题。
Array.prototype.map() - MDN
编辑
这将为您提供正确的成对组合。
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;
);
Array splice method - MDN
这是相同代码的更易读版本。
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;
);
【讨论】:
这里是原型jsfiddle.net/rlemon/qtxHx如果你发现你需要经常使用的话。【参考方案2】:据我所知没有。我认为你必须坚持使用嵌套循环。
这里有人问过类似的问题:Output each combination of an array of numbers with javascript也许你可以在那里找到答案。
【讨论】:
啊,太糟糕了。是的,这和我的问题一样!搜索的时候好像没找到。 我希望 Lodash 有这个【参考方案3】:查看问题后,此答案无法正确解决问题。该问题要求所有组合,但下面的函数组合了数组的所有相邻偶数和奇数索引。
这是我使用 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]
]
【讨论】:
我认为 reduce 和 forEach 不适用于 IE8 developer.mozilla.org/en-US/docs/JavaScript/Reference/… forEach 并不真正相关,因为它在这里仅用于演示目的。尽管正如您所说,减少在 IE8 上是有问题的。不过我相信你可以调整它。 我看到我的解决方案并没有真正回答这个问题。他要求所有组合,但我提供的解决方案提供了数组中所有偶数和奇数元素的组合。【参考方案4】:使用 ES6 语法,可以使用更短的@rlemon's answer:
["cat","dog","chicken","pig"].sort().reduce(
(acc, item, i, arr) => acc.concat(
arr.slice(i + 1).map(_item => [item, _item])
),
[])
根据 OP 的问题,这会处理 undefined
s,并且还只输出 unique 组合。
【讨论】:
【参考方案5】:这是一个通用的 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);
【讨论】:
【参考方案6】:最有效和最简单的解决方案可以减少和切片。但是,如果您只想获取值。您可以使用生成器。
// 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 ]
*/
【讨论】:
以上是关于javascript数组中条目的成对组合的主要内容,如果未能解决你的问题,请参考以下文章