knocked loose
knocked loose

Reputation: 3304

Performing the same filter and map function on 2 separate arrays

I am trying to filter through and then map 2 separate arrays. Normally I would just combine them, but I would like to keep them separate to make some logic later on a little easier.

Basically, I have 2 arrays:

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

I want to run (2) filters and (1) across these arrays like so:

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

However, I need to run the exact same filters, without merging my two arrays. So filtering a new variable with [...arr1, ...arr2] is out of the questions

I've been trying to do something along the lines of:

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

But I don't believe concat can process with filter.

Are there another array methods that might help me handle this, I can't seem to get the correct result

Upvotes: 0

Views: 255

Answers (1)

Tyler Roper
Tyler Roper

Reputation: 21672

Your best bet is to probably just create a separate function to do this, like so...

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

That said, I know you specified that you wanted to keep the methods separate for more complex logic, however I'd still suggest using reduce() to limit iterations.

You could alter your method to take a list of filter expressions and a map, applying them within a reduce(). This would keep your separated/clean filter functionality, while still using a more efficient array method in 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));

Or if you don't mind 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));

Upvotes: 2

Related Questions