Iterating over JavaScript objects declaratively or how to map, filter and reduce on objects
Photo by chuttersnap on Unsplash

Plain javascript objects are very useful, although ES6 provides Map data 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.entries returns an array of [key, value] pairs, we iterate over the array and eventualy build up what we want.

map

It takes an object obj and a functioni fun and returns a new Object with same keys and fun applied 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 fun applied 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 fun applied 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
['Amirali Esmaeili']
['JavaScript', 'Functional Programming', 'Js', 'ES6']