创建过滤器功能

时间:2014-07-22 14:59:53

标签: javascript arrays

我正在通过一系列测试来学习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。 inputiteratingFunction返回布尔值。应将所有真值添加到新数组中。

我目前正在使用此版本的过滤功能传递所有规格:

// **** 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函数上的额外功能。

1 个答案:

答案 0 :(得分:2)

您可以forEach实施mapfilterreduce,因此您可能应该首先使用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;,以便以不纯的代码为代价获得更好的效果。