2016-12-16 94 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); 
} 
相关问题