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

时间:2017-11-15 19:09:47

标签: javascript node.js

我之前已经问过这个问题,但我找不到问题/答案!

基本上我想创建它:

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;
    });

5 个答案:

答案 0 :(得分:2)

如果没有,您可以迭代数组并连接值,否则返回空数组。



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);




答案 1 :(得分:2)

可能无法将这两种方法(.map.filter)结合起来,因为.filter对元素和.map没有做任何逻辑始终从给定数组返回每个元素。 Hovewer你可以尝试.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);




答案 2 :(得分:1)

reduce肯定能解决问题:

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

答案 3 :(得分:1)

正如你所说,减少可能是要走的路:



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

function mapAndFilter(array, filterFunc, mapFunc) {
    return array.reduce((p, c) => {
        if (filterFunc(c)) p.push(mapFunc(c));
        return p;
    }, []);
}

const mapFilteredArray = mapAndFilter(myArray, x => x % 2 === 0, x => x*2);
console.log(mapFilteredArray);




根据需要调整该功能以继续使用阵列原型。

答案 4 :(得分:1)

根据您的示例代码,您的问题已经以特定方式得到了解答。

如果您要完成的是filtermap的通用函数(虽然它不是map,但它是reduce),这是你在找什么:

var filterAndReduce = function(arr, filterFn, fn) {
  return arr.reduce(function(r, a) {
        return r.concat(filterFn(a) ? [] : fn(a));
  }, []);
};

您可以这样使用它:

filterAndReduce([1,2,3,4,5], function(i) {
     return i % 2;
},
function(i) {
    return i * 2
});