我正在寻找一种在EcmaScript 6中计算笛卡尔积的方法
示例:
product([["I", "They"], ["watch", "drink"], ["the sea", "the juice"]])
预期结果:
[["I", "watch", "the sea"], ["I", "watch", "the juice"], ["I", "drink", "the sea"], ["I", "drink", "the juice"], ["They", "watch", "the sea"], ["They", "watch", "the juice"], ["They", "drink", "the sea"], ["They", "drink", "the juice"]]
示例:
product([[-1, -2], [10, 20]])
预期结果:
[[-1, 10], [-1, 20], [-2, 10], [-2, 20]]
答案 0 :(得分:2)
“假装JavaScript是Haskell”版本:
const re = g => a => ({
[Symbol.iterator]: () => g(a)
})
const cons = x => re(function* (xs) {
yield x
yield* xs
})
const map = f => re(function* (xs) {
for (const x of xs)
yield f(x)
})
const ap = fs => re(function* (xs) {
for (const f of fs)
for (const x of xs)
yield f(x)
})
const product = ([x, ...xs]) =>
x ? ap(map(cons)(x))(product(xs)) :
[[]]
使用如下(嗯,实际上不要):
for (const l of product([arr1, arr2, arr3]))
callback(...l)
re
使纯粹的生成器可重用。
答案 1 :(得分:1)
基于Ryan的想法:
let flatten = arr => [].concat(...arr);
function product([x, ...xs]) {
if(!x) return [[]];
let next = product(xs);
return flatten(x.map(a =>
next.map(b => [a, ...b])
));
}