Iterating over JavaScript objects declaratively or how to map, filter and reduce on objects

Amirali Esmaeili
Sanjagh
Published in
3 min readJul 25, 2019
Photo by chuttersnap on Unsplash

Plain javascript objects are very useful, although ES6 provides Mapdata structure, it’s still common to use them as key-value structures. But iterating over them its not as easy as using array higher order functions like filter or reduce, what if there exist such functions for js objects too.

Let’s write some of them with the help of Object.entries, folding, spread operator and computed property names (aka dynamic keys).

The idea behind all functions we are going to implement is the same, Object.entriesreturns an array of [key, value]pairs, we iterate over the array and eventualy build up what we want.

map

It takes an object objand a functioni funand returns a new Object with same keys and funapplied on all property values. Implementation is pretty simple , we reduce the array retuned by object entries with initial value of {}and add one property (which is the originial property with funapplied on it) in each step:

in reducer we flatten the previous object (accumulator) and add the new property.

filter

filter implementation is pretty similar to map but in each step instead of adding the funapplied property we will check whether predicate satisfies or not and using ternary we will return current property (inside an object) or an empty object and then using spread operator we some how flatten ternary result.

reduce

reduce takes three arguments the input object, the reducer function and an initial value.

try to implement fitler and map using implemented reduce function.

Examples

Lets say we have an object of fruits like this:

const fruits = {
apple: {
qty: 300,
color: "green",
name: "apple",
price: 2
},
banana: {
qty: 130,
color: "yellow",
name: "banana",
price: 3
},
orange: {
qty: 120,
color: "orange",
name: "orange",
price: 1.5
},
melon: {
qty: 70,
color: "yellow",
name: "melon",
price: 5
}
};

and want to map them into their colors:

const myFruits = map(fruits, (_, fruit) => fruit.color);
/*
{ apple: 'green',
banana: 'yellow',
orange: 'orange',
melon: 'yellow' }
/*

or filter items with price less than or equal 2:

const myFruits = filter(fruits, (_, fruit) => fruit.price <= 2);
/*
{ apple: { qty: 300, color: 'green', name: 'apple', price: 2 },
orange: { qty: 120, color: 'orange', name: 'orange', price: 1.5 } }
/*

or convert them into an array:

const myFruits = reduce(fruits, (prev, _, fruit) => [...prev, fruit], []);
/*
[ { qty: 300, color: 'green', name: 'apple', price: 2 },
{ qty: 130, color: 'yellow', name: 'banana', price: 3 },
{ qty: 120, color: 'orange', name: 'orange', price: 1.5 },
{ qty: 70, color: 'yellow', name: 'melon', price: 5 } ]
*/

Other functions

Using the idea we used to implement map , filter and reduce you can implement other functions like every , some , find and more.

--

--