Functional Programming – basic functions in pure JS

Jump to:

Exemplary array of objects:

var people = [
 { "id": 1, "first_name": "Richard", "gender": "Male", "age": 38}, 
 { "id": 2, "first_name": "Elizabeth", "gender": "Female", "age": 32}, 
 { "id": 3, "first_name": "Carlos", "gender": "Male", "age": 38}, 
 { "id": 4, "first_name": "Paula", "gender": "Female", "age": 27}, 
 { "id": 5, "first_name": "Maria", "gender": "Female", "age": 32}, 
 { "id": 6, "first_name": "Benjamin", "gender": "Male", "age": 31}, 
 { "id": 7, "first_name": "Carol", "gender": "Female", "age": 29}, 
 { "id": 8, "first_name": "Alan", "gender": "Male", "age": 37}, 
 { "id": 9, "first_name": "Clarence", "gender": "Male", "age": 40}, 
 { "id": 10, "first_name": "Gloria", "gender": "Female", "age": 28}
];

 

filter

Filter people by gender – jsFiddle

function filter(collection, fn){
	var filtered = [];
	
	for (var i=0; i<collection.length; i++) {
		if( fn(collection[i]) )
			filtered.push(collection[i]);
	}
	return filtered;	
};

var p = filter(people, function(person){
	return person.gender === 'Female';
});

console.log(p); // 5 people

 

map

Uppercase all names – jsFiddle

function map(collection, fn) {
	var mapped = [];

	for (var i=0; i<collection.length; i++) {
		mapped.push(
			fn(collection[i])
		);
	}

	return mapped;	
}

var p  = map(people, function(person){
	return person.first_name.toUpperCase();
});

console.log(p); //["RICHARD", "ELIZABETH", "CARLOS", "PAULA", "MARIA", "BENJAMIN", "CAROL", "ALAN", "CLARENCE", "GLORIA"]

 

reduce

Reduce array to one value. Initial value is needed because ‘last’ is undefined at first – jsFiddle

function reduce(collection, fn, initial) {
	var last = initial;

	for (var i=0; i<collection.length; i++) {
		last = fn( last, collection[i] );
	}

	return last;	
}

// get age from people array of objects an put it into separate array
var ageArray = map(people, function(person){ 
	return person.age;
});

// average age
var avg  = reduce(ageArray, add, 0) / ageArray.length;

console.log(Math.round(avg)); // 33

 

groupBy

Group people by gender – jsFiddle

function groupBy(collection, fn) {
	var grouped = {};
	var groupName;

	for (var i=0; i<collection.length; i++) {
		groupName = fn(collection[i]);	

		if(!grouped[groupName])
			grouped[groupName] = [];

		grouped[groupName].push(collection[i]);
	}

	return grouped;
};

// group people by gender
var byGender  = groupBy(people, function(person){
	return person.gender;
});

console.log(byGender); // {Male: Array[5], Female: Array[5]}

 

pluck

Create new array based on one property – jsFiddle

function pluck(collection, property) {
	return map(collection, function (item) {
		return item[property];
	});
};

var names  = pluck(people, 'first_name');

console.log(names); // ["Richard", "Elizabeth", "Carlos", "Paula", "Maria", "Benjamin", "Carol", "Alan", "Clarence", "Gloria"]

 

mean

jsFiddle

// uses 'pluck', 'reduce', 'add'
function mean(collection, property) {
	if(property){
		collection = pluck(collection, property);
	}

	return reduce(collection, add, 0) / collection.length;
};

// get average age of people 
var avgAge = mean(people, 'age');

console.log(Math.round(avgAge)); // 33

 

All in one example

All functions together within common namespace ‘fp’ – jsFiddle

var fp = {};


fp.add = function(a, b) {
	return a+b;
};

// filter collection
fp.filter = function(collection, fn){
	var filtered = [];

	for (var i=0; i<collection.length; i++) {
		if( fn(collection[i]) )
			filtered.push(collection[i]);
	}

	return filtered;	
};

// 
fp.map = function(collection, fn) {
	var mapped = [];

	for (var i=0; i<collection.length; i++) {
		mapped.push(
			fn(collection[i])
		);
	}

	return mapped;	
};

// reduce array to one value
fp.reduce = function(collection, fn, initial) {
	var last = initial;

	for (var i=0; i<collection.length; i++) {
		last = fn( last, collection[i] );
	}

	return last;	
};

// group array by property
fp.groupBy = function (collection, fn) {
	var grouped = {};
	var groupName;

	for (var i=0; i<collection.length; i++) {
		groupName = fn(collection[i]);	

		if(!grouped[groupName]){
			grouped[groupName] = [];
		}
			
		grouped[groupName].push(collection[i]);
	}

	return grouped;
};

// take one property and make array of it
fp.pluck = function (collection, property) {
	return fp.map(collection, function (item) {
		return item[property];
	});
};


// array or array of objects
fp.mean = function (collection, property) {
	if(property){
		collection = fp.pluck(collection, property);
	}

	return fp.reduce(collection, fp.add, 0) / collection.length;
};



// filter
var filter = fp.filter(people, function(person){
	return person.age > 30;
})
console.log('filter - people of age above 30: ', filter);

// map
var map = fp.map(people, function(person){
	return person.first_name.toUpperCase();
})
console.log('map - uppercase names: ', map);

// reduce
var ageArray = fp.map(people, function(person){ 
	return person.age;
});
var avg  = fp.reduce(ageArray, fp.add, 0) / ageArray.length;
console.log('reduce - average age:', Math.round(avg)); // 33

// groupBy
var byGender  = fp.groupBy(people, function(person){
	return person.gender;
});
console.log('groupBy - group people by gender:', byGender); // {Male: Array[5], Female: Array[5]}

// pluck
var names  = fp.pluck(people, 'first_name');
console.log('pluck - names: ', names); // ["Richard", "Elizabeth", "Carlos", "Paula", "Maria", "Benjamin", "Carol", "Alan", "Clarence", "Gloria"]

// mean
var mean = fp.mean(people, 'age');
console.log('mean - average age: ', Math.round(mean)); // 33

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>