在2个独立的阵列上执行相同的过滤器和映射功能

时间:2019-03-13 18:39:10

标签: javascript arrays ecmascript-6

我正在尝试过滤,然后映射2个单独的数组。通常,我只是将它们组合在一起,但是我想将它们分开,以便稍后进行一些逻辑化。

基本上,我有2个数组:

const arr1 = [ {obj1}, {obj2}, {obj3} ];
const arr2 = [ {obj4}, {obj5}, {obj6} ];

我想像这样在这些数组上运行(2)过滤器和(1):

arr1.filter(obj => obj.color !== 'red')
.filter(obj => obj.shape !== 'circle')
.map(obj => {
  //logic
}

但是,我需要运行完全相同的过滤器,而不合并两个数组。因此,用[...arr1, ...arr2]过滤新变量是不可能的

我一直在尝试做以下事情:

arr1.concat(arr2).filter.... 

但是我不相信concat可以使用过滤器进行处理。

还有其他数组方法可以帮助我解决这个问题吗,我似乎无法获得正确的结果

1 个答案:

答案 0 :(得分:2)

您最好的选择是像这样创建一个单独的函数来完成此操作...

const arr1 = [ {color: "blue", shape: "triangle"}, {color: "red", shape: "square"}, {color: "green", shape: "circle"} ];
const arr2 = [ {color: "purple", shape: "diamond"}, {color: "yellow", shape: "square"}, {color: "orange", shape: "circle"} ];

const applyFiltersAndMap = (array) => {
  return array.filter(obj => obj.color !== 'red')
              .filter(obj => obj.shape !== 'circle')
              .map(obj => `${obj.color} ${obj.shape}`);
};

console.log(applyFiltersAndMap(arr1));
console.log(applyFiltersAndMap(arr2));

也就是说,我知道您指定要针对更复杂的逻辑将方法分开,但是我仍然建议使用reduce()来限制迭代。

您可以更改方法以获取过滤器表达式和映射的列表,并在reduce()中应用它们。这样可以保留分离/干净的过滤器功能,同时在reduce中仍使用更有效的数组方法。

const arr1 = [ {color: "blue", shape: "triangle"}, {color: "red", shape: "square"}, {color: "green", shape: "circle"} ];
const arr2 = [ {color: "purple", shape: "diamond"}, {color: "yellow", shape: "square"}, {color: "orange", shape: "circle"} ];

const applyFiltersAndMap = (array, filters, mapper) => {
  return array.reduce((out,e) => {
    if (filters.every(f => f(e))) out.push(mapper(e)); //filter and map
    return out;
  }, []);
};

const filters = [                                  //your filter functions
  obj => obj.color !== 'red',
  obj => obj.shape !== 'circle'
];
const mapper = obj => `${obj.color} ${obj.shape}`; //your map function

console.log(applyFiltersAndMap(arr1, filters, mapper));
console.log(applyFiltersAndMap(arr2, filters, mapper));

或者如果您不介意extending Array.prototype ...

const arr1 = [ {color: "blue", shape: "triangle"}, {color: "red", shape: "square"}, {color: "green", shape: "circle"} ];
const arr2 = [ {color: "purple", shape: "diamond"}, {color: "yellow", shape: "square"}, {color: "orange", shape: "circle"} ];

Array.prototype.applyFiltersAndMap = function(filters, mapper) {
  return this.reduce((out,e) => {
    if (filters.every(f => f(e))) out.push(mapper(e)); //filter and map
    return out;
  }, []);
};

const filters = [                                  //your filter functions
  obj => obj.color !== 'red',
  obj => obj.shape !== 'circle'
];
const mapper = obj => `${obj.color} ${obj.shape}`; //your map function

console.log(arr1.applyFiltersAndMap(filters, mapper));
console.log(arr2.applyFiltersAndMap(filters, mapper));