Jake
Jake

Reputation: 149

Using Reduce instead of chaining Filter and Map

I have a function takes an array of dog objects and returns an array of the names of all the owners.

    dogs = [
      {name: 'Archie', breed: 'Lurcher', owner: 'Jack'},
      {name: 'Charlie', breed: 'Pug', owner: 'John'},
      {name: 'Buddy', breed: 'Pug', owner: 'Mike'}
    ]

I get the result by chaining filter and map, but this means I am looping over the same list twice. I know this can be done using Reduce but unsure how I would do this. A lot of examples on Reduce seem to be with numbers which is a little confusing when trying to work my problem out.

Any help would be appreciated. Thanks

function getOwners(dogs) {

   return dogs.filter(dog => dog.breed === 'Pug').map(dog => dog.owner);
}

  returns ['John', 'Mike']

Upvotes: 5

Views: 6241

Answers (2)

Artyer
Artyer

Reputation: 40791

You pass an initial array, and whilst reducing only push the mapped value if the value hasn't been filtered out.

const filteredMap = (filter, mapping) => {
  return arr => Array.prototype.reduce.call(arr, (accumulator, value) => {
    if (filter(value)) accumulator.push(mapping(value));
    return accumulator;
  }, []);
};

const getOwners = filteredMap(dog => dog.breed == 'Pug', dog => dog.owner);

getOwners([
  {name: 'Archie', breed: 'Lurcher', owner: 'Jack'},
  {name: 'Charlie', breed: 'Pug', owner: 'John'},
  {name: 'Buddy', breed: 'Pug', owner: 'Mike'}
]);  // => [ 'John', 'Mike' ]

It might be more clear to write it out as a loop though:

const filteredMap = (filter, mapping) => {
  return arr => {
    const res = [];
    for (const value of arr) {
        if (filter(value)) res.push(mapping(value));
    }
    return res;
  };
};

Upvotes: 0

Teiem
Teiem

Reputation: 1619

The function you are looking for is:

dogs.reduce((total, current) => current.breed === "Pug" ? [...total, current.owner] : total, []);

we go over dogs and test current.breed === "Pug" for every element, if it is true, we add the owner of the current dog to the total array, else we keep the total array the way it is.

Upvotes: 12

Related Questions