2017-04-22 71 views
0

我正在尋找一種方法來計算笛卡爾乘積中的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

什麼是嵌套'for..of'循環,如果'arr2'不和的元素目的'arr1'? – guest271314

+0

笛卡爾產品! –

+0

認爲,這比真正有用的東西更具挑戰性! –

回答

2

的「假裝JavaScript是哈斯克爾」版本:

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使一個純生成器可重用。

+0

謝謝!很有意思 ! –

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]) 
    )); 
}