2016-12-16 49 views
1

我已經重新創建的foreach +地圖+減少功能JS:如何使用reduce函數在javascript函數式編程中查找一組數組之間的交集/並集?

function forEach(array, callback) { 
for (var i=0;i<array.length;i++) { 
    callback(array[i]) 
    } 

} 
function mapWith(array, callback) { 
    var output= []; 
    forEach(array , function(el){ 
    return output.push(callback(el)) 
    }); 
    return output; 

} 
function reduce(array, callback, initialValue) { 
    mapWith(array, function(el){ 
    return initialValue = callback(initialValue, el); 
    }) 
    return initialValue; 

} 

現在我會怎麼用降低找到一組陣列之間的交集?

function intersection(arrays) { 

} 
// console.log(intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20])); 
// should log: [15, 5] 

此外,我將如何比較輸入數組並返回一個包含所有元素的新數組。如果有重複的元素,只添加一次到新的數組。從第一個輸入數組的第一個元素開始的元素的順序被保留。

function union() { 
} 

// console.log(union([5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5])); 
// should log: [5, 10, 15, 88, 1, 7, 100] 
+0

FWIW,來源於http://csbin.io/callbacks –

回答

1

現在怎麼會我用降低找到一組陣列之間的交集?

使用reduce的實現將依次獲取每個數組,並從結果中消除(濾除)元素,如果它們不存在於該數組中。

function intersection(arrays) { 
    return reduce(arrays, (result, array) => 
    filter(result, e => array.includes(e))); 
}; 

這是假設你已經編寫了自己filter

function filter(array, callback) { 
    var output= []; 
    forEach(array , function(el) { 
    if (callback(el)) output.push(el); 
    }); 
    return output; 

} 

另一個想法是通過連接所有的數組開始:

function concat(arrays) { return [].concat(...arrays); } 

然後過濾結果只包括元素髮生在所有陣列中:

function intersection(arrays) { 
    return concat(arrays).filter(e => arrays.every(a => a.includes(e)); 
} 

如果你不希望使用內置Array#every,並繼續向下編寫自己的路徑:

function every(array, callback) { 
for (var i = 0; i < array.length; i++) 
    if (!callback(array[i])) return false; 
return true; 
} 

使用和自己filterintersect就變成了:

function intersection(arrays) { 
    return filter(concat(arrays), e => every(arrays, a => a.includes(e))); 
} 

Array#includes是ES7,可能不支持您最喜歡的瀏覽器。在這種情況下,請改用a.indexOf(e) !== -1,或者自己寫。

有些人可能喜歡寫更多的「語義」爲:

function intersection(arrays) { 
    const inAll = e => every(arrays, a => a.includes(e)); 

    return filter(concat(arrays), inAll); 
} 

此外,如何將我比較輸入數組,並返回一個包含所有元素的數組。如果有重複的元素,只添加一次到新的數組。從第一個輸入數組的第一個元素開始的元素的順序被保留。

我不知道「比較」是什麼意思。無論如何,你顯然想要什麼,將它們連接起來,並運用一些uniq樣工具:

function union(arrays) { 
    return uniq(concat(arrays)); 
} 

還有的uniq那裏許多實現。這裏有一個很簡單的例子:

function uniq(arr) { 
    return arr.filter((elt, i) => arr.indexOf(elt) === i); 
} 
相關問題