我正在通过一系列测试来学习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
返回布尔值。应将所有真值添加到新数组中。
我目前正在使用此版本的过滤功能传递所有规格:
// **** FILTER FUNCTION ****
function filter(array, itfunction){
var newArray = [];
map(array, function(item){
if(itfunction(item)){
newArray.push(item);
}
});
return newArray;
}
我觉得这不是最佳的,因为map应该返回一个新数组,并且我将项目推送到我在filter函数中创建的新数组中。我真的可以使用forEach()函数并获得相同的结果。我不觉得我在这里正确使用地图功能。有没有人对如何更好地实现map函数有任何建议,所以我不必在我的过滤函数中实例化和创建一个新数组?我宁愿尝试让我的map函数完成所有的工作,因为这是它目前在forEach函数上的额外功能。
答案 0 :(得分:2)
您可以forEach
实施map
,filter
和reduce
,因此您可能应该首先使用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是累加器的简称)
function filter(array, tester) {
return reduce(array, function(acc, value, index){
if (tester(value, index)) {
return acc.concat([value]);
}
else {
return array;
}
}, []);
}
还有地图和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;
,以便以不纯的代码为代价获得更好的效果。