UNPKG

kevinqdang

Version:

An npm functional programming library project

387 lines (358 loc) 11.5 kB
'use strict'; // YOU KNOW WHAT TO DO // /** * each: Designed to loop over a collection, Array or Object, and applies the * action Function to each value in the collection. * * @param {Array or Object} collection: The collection over which to iterate. * @param {Function} action: The Function to be applied to each value in the * collection */ function each(collection, action) { if(Array.isArray(collection)) { for(var i = 0; i < collection.length; i++) { action(collection[i], i, collection); } } else { for (var key in collection) { action(collection[key], key, collection); } } } module.exports.each = each; /** * Identity: Returns anything that is put into the parameter * * @param {Anything} anything: any value * @return {Anything} return any value * **/ function identity(anything) { return anything; } module.exports.identity = identity; /** * typeOf: Is to return a string of what kind of value is put into the parameter * * @param {Anthing} anything: any value * @return {String} Returns a string **/ function typeOf(anything) { if(Array.isArray(anything)){ return "array"; } else if (anything === null){ return "null"; }else { return typeof(anything); } } module.exports.typeOf = typeOf; /** * First: Designed to loop into an array and pulling out either the first element or an array of the elements. * If not giving an array then it is returns and an empty array. If the number parameter is not giving * it returns the first element of the array * * @param {Array} array: Array * @param {Number} number: Numbers * @return {Array} returns how many number of element in the array or the first element **/ function first(array , number){ let results = []; if (!Array.isArray(array) || number < 0) { return []; } else if (!typeof(number) === "number" || !number) { return array[0]; } else { if (number > array.length) { return array; } else { for (let i = 0; i < number; i++) { results.push(array[i]); } } return results; } } module.exports.first = first; /** * Last: Designed to loop thru the array to get either the last element or as many number inside the number parameter * If not an array return an empty array. * * @param {Array} array: array * @param {Number} number: Numbers * @return {Array} returns how many number of elements of the end of the array or the last element * **/ function last(array, number) { let results = []; if (!Array.isArray(array) || number < 0) { return []; } else if (!typeof(number) === "number" || !number) { return array[array.length -1]; } else { if (number > array.length) { return array; } else { for (let i = array.length - number; i < array.length; i++) { results.push(array[i]); } } return results; } } module.exports.last = last; /** * IndexOf: Designed to loop inside of an array to find the giving value and return the index. If the value is not found inside * the array a -1 is returned. * @param {Array} array: Array * @param {Number || String} value: Numbers or strings * @return {Number} Returning the index of the element or a -1 * **/ function indexOf(array, value){ for(let i = 0; i < array.length; i++) { if(array[i] === value){ return i; } } return -1; } module.exports.indexOf = indexOf; /** * filter: Designed to loop thru either an array or object and then giving a function as "test" test to see if any of the element * is meet, it is then pushes into empty array, then return all the element inside the array that passes the test function * * @param {Array || Object} collection: array or object * @param {Function} test: A function that return a boolean * @return {Array} Array of values that passes the test * **/ function filter(collection, test){ let results = []; each(collection, function (element, index, collection) { if (test(element, index, collection)) { results.push(element); } }); return results; } module.exports.filter = filter; /** * Reject: Designed to loop thru an array or object and giving a function "test" to test weather each element fails the test * then push the failed element into an array and return all the failed element in an array * * @param {Array || Object} collection: array or object * @param {Function} test: A function that returns a boolean * @return{Array} An array of values that failed the test * * */ function reject(collection, test){ return filter(collection, function rejectFunc(element, index, array){ if(!test(element, index, array)){ return true; } }); } module.exports.reject = reject; /** * Partition: Designed to loop thru an array giving a function "test" testing weather each element passes or fails. * Returns two array inside of one with one array having all the passed element and the other having all the failed * * @param: {Array} array: Array * @param:{Function} test: A function that returns a boolean * @return {Array} Returning one array of two different array of passed and failed * * */ function partition(array, test){ return [filter(array, test), reject(array, test)]; } module.exports.partition = partition; /** * Unique: Designed to loop inside of an array and removing all the duplicate while leaving only one of the same kind inside the array * * @param:{Array} array: Array * @return:{Array} Returns the array of one kind of element that was removed * * */ function unique(array){ let results = []; for (let i = 0; i < array.length; i++) { if (indexOf (results, array[i]) === -1) { results.push(array[i]); } } return results; } module.exports.unique = unique ; /** * Map: Designed to loop inside an array or object, giving a function "action" does something to the elements and then pushed * into an empty array and return that array. * * @param: {Array || Object} collection: Array or object * @param: {Function} action: A function that modify each of the vaule * @return: {Array} Returns an array with each value modified * * */ function map(collection, action) { let results = []; each(collection, function (element, index, collection) { results.push(action(element, index, collection)); }); return results; } module.exports.map = map; /** * Pluck: Designed to loop inside an array and object, giving a property finding that property and returning array of that giving * property value * * @param:{Array || Object} array: An array of object * @param:{Object} property: A value that is inside the object * @return{Array} Returns an array of the giving property **/ function pluck(collection, property){ return map(collection, function(element, index, array){ for(let key in element){ if(key === property){ return element[key]; } } }); } module.exports.pluck = pluck; /** * Contains: Designed to loop in an array, giving a value and checking if that value is inside the array * returning a boolean * * @param:{Array} array: Array * @param:{Number || String} value: Anything * @return:{Boolean} Returns a boolean * */ function contains(array, value){ for(var i = 0; i < array.length; i++) { if(array[i] === value){ return true; } } return false; } module.exports.contains = contains; /** * Every: Designed to loop inside array or object, giving a function "test". Testing to see if any of the element passes the test * if one of the element fails then it will return false. If all the element passes the test then return true. * * @param:{Array || Object} collection: Array or object * @param:{Function} test: A function * @return{Boolean} Returns a boolean * */ function every(collection, test){ if (typeof test !== "function") { for (let i = 0; i < collection.length; i++){ if(collection[i] === false){ return false; } } return true; } else{ if(reject(collection, function (elemenet, index, collection){ if(test(elemenet, index, collection)){ return true; } }).length > 0){ return false; } else { return true; } } } module.exports.every = every; /** * Some: Designed to loop into array or object, giving a function "test". Testing each element and if one of the element is true * return true. If all the element fails then the result return false * * @param:{Array || Object} collection: Array or object * @param:{Function} test: A function * @return:{Boolean} Returns a boolean * */ function some(collection, test){ if (typeof test !== "function") { for (let i = 0; i < collection.length; i++){ if(collection[i] === false){ return false; } } return true; } else{ if(filter(collection, function (elemenet, index, collection){ if(test(elemenet, index, collection)){ return true; } }).length > 0){ return true; } else { return false; } } } module.exports.some = some; /** *Reduce: Designed to loop inside an array or object, giving a function "action", and a seed. If seed is not defined then seed is * the first element of the array. Then from there the action function is then modifiy each element. Returns could be anything * an array or object or string or a number. * * @param:{Array || Object} collection: Array or object * @param:{Function} action: A function that modifiy * @param:{Value} seed: Could be any value (array, object, string, or number) * @return:{Anything} Returns could be anything * */ function reduce(collection, action, seed){ let previousSum; if (seed === undefined) { for(let i = 1; i < collection.length; i++) { seed = collection[0]; if (i === 1) { previousSum = action(seed, collection[i], i); } else { previousSum = action(previousSum, collection[i], i); } } } else { each(collection, function (element, index, collection) { if (index === 0) { previousSum = action(seed, element, index); } if (index !== 0) { previousSum = action(previousSum, element, index); } }); } return previousSum; } module.exports.reduce = reduce; /** * Extend: Having a nested objects and copying the keys-values, not duplicated it. Returning the nested objects into one * * @param{Object} obj1: Object * @param{Object} obj2: object * @param{Object} moreObj: more object * @return{Object} Returning the combined objects into one object * */ function extend(object1, object2, object3) { Object.assign(object1, object2); if(object3) { Object.assign(object1, object2, object3); } return object1; } module.exports.extend = extend;