我正在通过一系列测试来学习 JavaScript。我最近制作了一个 forEach 和 map 函数,如下所示:
// **** FOR EACH ****
function forEach(inputArray, iteratingFunction){
for(var i =0; i < inputArray.length; i++){
iteratingFunction(inputArray[i]);
}
}
// **** MAP FUNCTION ****
function map(inputArray, inputFunction){
var newMapArray = [];
forEach(inputArray, function(element){
newMapArray.push(inputFunction(element));
});
return newMapArray;
}
现在我必须制作一个过滤功能。它需要一个数组和一个 inputFunction。 input
或 iteratingFunction
返回 bool 值。所有真值都应添加到新数组中。
我目前正在通过此版本过滤器功能的所有规范:
// **** FILTER FUNCTION ****
function filter(array, itfunction){
var newArray = [];
map(array, function(item){
if(itfunction(item)){
newArray.push(item);
}
});
return newArray;
}
不过我觉得这不是最佳选择,因为 map 应该返回一个新数组,而我正在将项目推送到我在过滤器函数中创建的新数组中。我真的可以使用 forEach() 函数并获得完全相同的结果。我觉得我在这里没有正确使用 map 功能。有没有人对如何更好地实现 map 函数有任何建议,这样我就不必在我的 filter 函数中实例化和创建一个新数组?我宁愿尝试让我的 map 函数完成所有工作,因为这是它当前对 forEach 函数的额外功能。
最佳答案
您可以根据reduce
实现forEach
、map
和filter
,因此您可能应该首先从 reduce
开始。
function reduce(array, iterator, accumulator) {
var index = -1,
length = array.length;
if (arguments.length == 2 && length) {
accumulator = array[++index];
}
while (++index < length) {
accumulator = iterator(accumulator, array[index], index, array);
}
return accumulator;
} // modified version of lodash's reduce
现在我们可以实现filter
(acc是accumulator的缩写)
function filter(array, tester) {
return reduce(array, function(acc, value, index){
if (tester(value, index)) {
return acc.concat([value]);
}
else {
return array;
}
}, []);
}
还有 map 和 forEach 的乐趣:
function map(array, mapper){
return reduce(array, function(acc, item, index){
return acc.concat([mapper(item, index)]);
}, []);
}
function forEach(array, handler){
reduce(array, function(acc, item, index){
handler(item, index);
}, undefined);
}
注意:这些是纯粹的实现;您可以将 return acc.concat([x])
替换为 acc.push(x); return acc;
以不纯代码为代价获得稍微更好的性能。
关于javascript - 创建过滤函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24890873/