Real Examples of Javascript Functional Programming for Beginners

Let’s put some context

Let’s say I’m a work and today Angela come to ask me something.
She “works” at marketing and asks me to give her a list of our users with email and names, so they can write “customized messages” to our clients.

const users = [
{
id: 4545,
nickname: "franky",
name: "Frank",
email: "frank4545@aol.com",
country: "US",
subscriber: true
},
{
id: 4546,
nickname: "castortroy",
name: "Troy",
email: "realtroy@gg.com",
country: "US",
subscriber: false
},
{
id: 4547,
nickname: "melly99",
name: "melody",
email: "darkistheday@cusual.io",
country: "IT",
subscriber: false
}
];

Introduction to the Map function

So without knowing any functional style programming, here it’s what I would do :

const users_without_extra_info = [];
for (user of users) {
users_without_extra_info.push({
name: user.name,
email: user.email
});
}
[
{ name: "Frank", email: "frank4545@aol.com" },
{ name: "melody", email: "darkistheday@cusual.io" },
{ name: "Troy", email: "realtroy@gg.com" }
];
const users_with_map = users.map(user => {
return {
name: user.name,
email: user.email
};
});
console.log(users_with_map);
[
{ name: "Frank", email: "frank4545@aol.com" },
{ name: "melody", email: "darkistheday@cusual.io" },
{ name: "Troy", email: "realtroy@gg.com" }
];
function userWitoutExtratInfo(user) {
return {
name: user.name,
email: user.email
};
}
users.map(userWitoutExtratInfo); // no suprise it also returns
// [ { name: 'Frank', email: 'frank4545@aol.com' },
// { name: 'melody', email: 'darkistheday@cusual.io' },
// { name: 'Troy', email: 'realtroy@gg.com' } ]
const users_for_angela_with_map = users.map(user => {
return {
name: user.name,
email: user.email
};
});
// VS
const users_for_angela = []; // not needed with map() (it return a new array)
for (user of users) {
// With map() I don't need to botter choosing how to loop over it, and I can't make mistakes
users_for_angela.push({
// here it's pretty much the same but I can't make the mistake of modifying my original array
name: user.name,
email: user.email
});
}

How to Filter using ‘filter’ function

The next day when I arrive late at work (my working habit) and she’s already at my desk.
I put down my backpack and turn on my computer while she explained to me that:

const users_no_aol = [];
for (user of users) {
if (!user.email.includes("aol.com")) {
// RIP AOL
users_no_aol.push({
name: user.name,
email: user.email
});
}
}
console.log(users_no_aol); // it prints:
// [ { name: 'melody', email: 'darkistheday@cusual.io' },
// { name: 'Troy', email: 'realtroy@gg.com' } ]
const all_users = users.map(user => {
return {
name: user.name,
email: user.email
};
});
const users_with_aol_filtered = all_users.filter(user => {
return !user.email.includes("aol.com");
});
console.log(users_with_aol_filtered); // and it prints:
// [ { name: 'melody', email: 'darkistheday@cusual.io' },
// { name: 'Troy', email: 'realtroy@gg.com' } ]
const all_users_for_angela = users.map(user => {
return {
name: user.name,
email: user.email
};
});
const users_aol_filtered = all_users_for_angela.filter(user => {
return !user.email.includes("aol.com");
});
// VS
const users_no_aols = [];
for (user of users) {
if (!user.email.includes("aol.com")) {
// it take only this line to filter with our for loop
users_no_aols.push({
name: user.name,
email: user.email
});
}
}
users
.map(user => {
return {
name: user.name,
email: user.email
};
})
.filter(user => {
return !user.email.includes("aol.com");
}); // and filter returns:
// [ { name: 'melody', email: 'darkistheday@cusual.io' },
// { name: 'Troy', email: 'realtroy@gg.com' } ]
users
.map(user => {
return { name: user.name, email: user.email }; // sometime one line code is better
})
.filter(user => {
return !user.email.includes("aol.com");
}); // same return returned by filter
// [ { name: 'melody', email: 'darkistheday@cusual.io' },
// { name: 'Troy', email: 'realtroy@gg.com' } ]

Sort function a concrete example

Let’s say I bring that list back to Angela.
Then she would probably ask me something more. Like Alphabetical ordering. If you had seen her desk (where her pencil are color ordered) you will know she will definitely ask for it.

users
.map(user => {
return { name: user.name, email: user.email };
})
.filter(user => {
return !user.email.includes("aol.com");
})
.sort((userA, userB) => {
if (userA.name.toLowerCase() < userB.name.toLowerCase())
return -1;
if (userA.name.toLowerCase() > userB.name.toLowerCase())
return 1;
return 0;
});
// sort returns :
// [ { name: 'melody', email: 'darkistheday@cusual.io' },
// { name: 'Troy', email: 'realtroy@gg.com' } ]
users
.map(user => {
return { name: user.name, email: user.email };
})
.filter(user => {
return !user.email.includes("aol.com");
})
.sort((userA, userB) => {
if (userA.name.toLowerCase() < userB.name.toLowerCase())
return -1;
if (userA.name.toLowerCase() > userB.name.toLowerCase())
return 1;
return 0;
})
.reverse(); // yep reverse ! No need to modify any thing to return:
// [ { name: 'Troy', email: 'realtroy@gg.com' },
// { name: 'melody', email: 'darkistheday@cusual.io' } ]
users
.map(user => {
return { name: user.name, email: user.email, nickname: user.nickname }; // here goes your dummy nickname
})
.filter(user => {
return !user.email.includes("aol.com");
})
.sort((userA, userB) => {
if (userA.name.toLowerCase() < userB.name.toLowerCase())
return -1;
if (userA.name.toLowerCase() > userB.name.toLowerCase())
return 1;
return 0;
})
.reverse(); // returns
// [ { name: 'Troy',
// email: 'realtroy@gg.com',
// nickname: 'castortroy' },
// { name: 'melody',
// email: 'darkistheday@cusual.io',
// nickname: 'melly99' } ]
users
.map(user => {
return { name: user.name, email: user.email, nickname: user.nickname };
}) // no more filter (isn't it nice to delete consecutive lines and get a new feature ?!)
.sort((userA, userB) => {
if (userA.name.toLowerCase() < userB.name.toLowerCase())
return -1;
if (userA.name.toLowerCase() > userB.name.toLowerCase())
return 1;
return 0;
})
.reverse();
users
.map(user => {
return { name: user.name, email: user.email, nickname: user.nickname };
})
.sort((userA, userB) => {
if (userA.name.toLowerCase() < userB.name.toLowerCase())
return -1;
if (userA.name.toLowerCase() > userB.name.toLowerCase())
return 1;
return 0;
})
.reverse()
.map(user => {
// could have been this above In the first map, but Angela could change one more time
return {
...user,
name: user.name.toUpperCase(),
nickname: user.nickname.toLowerCase()
};
})
; // returns:
// [ { name: 'TROY',
// email: 'realtroy@gg.com',
// nickname: 'castortroy' },
// { name: 'MELODY',
// email: 'darkistheday@cusual.io',
// nickname: 'melly99' },
// { name: 'FRANK', email: 'frank4545@aol.com', nickname: 'franky' } ]
let user_csv = users
.map(user => {
return {
name: user.name.toUpperCase(), // I bet she won't care about this anymore (It's almost the end of the day afterall)
email: user.email,
nickname: user.nickname.toLowerCase()
};
})
.sort((userA, userB) => {
if (userA.name.toLowerCase() < userB.name.toLowerCase())
return -1;
if (userA.name.toLowerCase() > userB.name.toLowerCase())
return 1;
return 0;
})
.reverse()
.map(user => Object.values(user).join(";")); // join each value of the user object with ";"
console.log(user_csv); // prints:
// [ 'TROY;realtroy@gg.com;castortroy',
// 'MELODY;darkistheday@cusual.io;melly99',
// 'FRANK;frank4545@aol.com;franky' ]
users
.map(user => {
return {
name: user.name.toUpperCase(),
email: user.email,
nickname: user.nickname.toLowerCase()
};
})
.sort((userA, userB) => {
if (userA.name.toLowerCase() < userB.name.toLowerCase())
return -1;
if (userA.name.toLowerCase() > userB.name.toLowerCase())
return 1;
return 0;
})
.reverse()
.map(user => Object.values(user).join(";"))
.map(csv_line => csv_line + ";"); // I could have done it one line before. But I like this way. One operation by map
// our last map returns:
// [ 'TROY;realtroy@gg.com;castortroy;',
// 'MELODY;darkistheday@cusual.io;melly99;',
// 'FRANK;frank4545@aol.com;franky;' ]
let whole_csv_string = "";
for (const line of toto) {
whole_csv_string = whole_csv_string + "\n" + line;
}
console.log(whole_csv_string); // prints:
// TROY;realtroy@gg.com;castortroy;
// MELODY;darkistheday@cusual.io;melly99;
// FRANK;frank4545@aol.com;franky;
proper_csv = my_list.reduce((whole_csv, csv_line) => whole_csv + "\n" + csv_line);
console.log(proper_csv); // prints:
// TROY;realtroy@gg.com;castortroy;
// MELODY;darkistheday@cusual.io;melly99;
// FRANK;frank4545@aol.com;franky;

A bit of functional programming theory :

I didn’t give any theoretical background explanations about functional programming.
That was on purpose. Functional programming is really mathematical oriented (as my understanding goes). In my opinion, it is too abstract to grasp quickly. That’s why I wrote this article.

Summary:

map -> map each element into a new format.
Could have been named: mapEach
explicit imaginary name: contrustNewArrayWithMappingFunction(mappingFunction)

Conclusion:

I hope it helps you see the big picture. Personally, I need concrete examples to memorize new concepts. I try to keep you entertained while reading this article (so your brain doesn’t pass out). Give it some clap if you like this article format.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
lsmod

lsmod

Self-taught programmer; passionate about Rust & Blockchains