开发者问题收集

如何在单循环中映射+过滤

2017-11-15
1540

我之前在 SO 上问过这个问题,但是我找不到问题/答案!

基本上我想创建这个:

Array.prototype.filterAndMap = function(){};

我可以像这样使用它:

[1,2,3,4,5].filterAndMap(function(){
     if(i % 2 === 0){
        return i*2;
     }
});

上面会返回:

  [4,8]

我认为实现这一点的最佳方法是使用 Array.prototype.reduce......但我不确定。

我想避免的是两次遍历列表:

   [1,2,3,4,5].filter(function(){
         return i % 2 === 0;
    })
    .map(function(i){
         return i * 2;
    });
3个回答

您可以迭代该数组,如果有效则连接该值,如果无效则连接一个空数组。

var array = [1, 2, 3, 4, 5],
    result = array.reduce(function(r, a) {
        return r.concat(a % 2 ? [] : 2 * a);
    }, []);
    
console.log(result);

ES6

var array = [1, 2, 3, 4, 5],
    result = array.reduce((r, a) => r.concat(a % 2 ? [] : 2 * a), []);
    
console.log(result);
Nina Scholz
2017-11-15

将这两种方法( .map.filter )结合起来可能不太现实,因为 .filter 不会对元素执行任何逻辑,而 .map 总是返回给定数组中的 每个 元素。但是您可以尝试 .reduce 方法,仅返回满足给定条件的元素。

const arr = [1,2,3,4,5];

const r = arr.reduce((s, a) => (a % 2 ? null : s.push(a * 2), s), []);

console.log(r);
kind user
2017-11-15

reduce 肯定能解决问题:

[1,2,3,4,5].reduce((arr, cur) => { 
   if(cur % 2 == 0){
      arr.push(cur * 2); 
   }
   return arr;
}, []);   // => [2, 4]
ajm
2017-11-15