UNPKG

staffordsmith

Version:

An npm functional programming library project

421 lines (392 loc) 12.7 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: Designed to return whatever value that is inserted. * * @param {Any Value}: This can be any one Value. * * @return The same exact value that was set as a param. * * Usage: * */ function identity(value){ return value; } module.exports.identity = identity; /** * typeOf: Designed to return the type of value in a string. * Types are one of: * - "string" * - "array" * - "object" * - "undefined" * - "number" * - "boolean" * - "null" * - "function" * * @param {value}: Can be any given value. * * @return {'String'}: Will be a string containing the type of value. * * Usage: * * function typeOf(value){ * if(Array.isArray(value)){ * return 'Array'; * }else if(value === null){ return 'null'; } return typeof value; * } * module.exports.typeOf = typeOf; * */ /** * first: Designed to take in two args(array, number). If array is not given it returns a * a []. Next it checks to see if a number is given || is not a number at all. If any of these * are true it will return the first element of the array. Then if the number is * more than array.length it will return the entire array. Lastly it will return * the first (whatever number is) elements of the array * * @param {array, number} * * @return See first Above. * * Usage: */ function first(array, number){ let list = []; if(!Array.isArray(array)){ return list; } if(!number || isNaN(number)){ return array[0]; }else if(number > array.length){ return array; }else{ for(var i = 0; i < number; i++){ list.push(array[i]); } } return list } module.exports.first = first; /** * last: Designed to return the last element in a array. It takes two args * (array, number) so if no array is past in || number is negative it will * retern a []. Then if no number is past in || number is NaN it will return the * last element in the array. Then if number is larger than array.length return * entire array. Otherwise it will loop over the array and return the last * (Whatever number is) elements * in the array. * * @param {array, number} * * Usage: * */ function last(array, number){ if(!Array.isArray(array) || number < 0){ return []; }else{ if(!number || isNaN(number)){ return array.length - 1; }else if(number > array.length){ return array }else{ return array.slice(array.length - number, array.length) } } } module.exports.last = last; /** * indexOf: Designed to take two args(array, value). It will loop thru the array * and return the first occurrance of the values Index. Next if the value is not * found in the array it will return -1. * * @param {array, value} * * Usage: */ function indexOf(array, value){ for(var i = 0 array.length; i++){ if(array[i] === value){ return i; }else{ } } return -1; } module.exports.indexOf = indexOf; /** * filter: Designed to take two args(array, function) first it will loop thru each * element in the array sending it thru the function(element,index,array) as params. * It will return a new array with all the elements that return true from the * function. * * @param {array, function} * * Usage: */ function filter(array, sort){ let page = []; for(let i = 0; i < array.length; i++){ const result = sort(array[i], i, array); if(result === true){ page.push(array[i]); } } return page; }; module.exports.filter = filter; /** * reject: Designed to take two args(array, function), it will loop over each element in * the array applying the function(element,index,array) to each element. It will * return a new array with the elements that returnes a false value from the function. * * @args {array, function} * Usage: */ function reject(array, function(element,i, array){ let box = [] if(.filter(array, function(element, i, array){ return !element; }).length > 0){ box.push(element) } }); module.exports.reject = reject; /** * partition: Designed to take two args(array, function), it will loop throught * array passing the function on each element in the array. It will return a * array that contains two sub arrays. One sub should contain truthy and one should * contain falsy. * * @args {array, function} * * Usage: */ function partition(array, function){ let result = []; let box = []; let bigBox = []; for(let i = 0; i < array.length; i++){ if(bunch(array[i], i, array) === true){ result.push(array[i]); }else{ box.push(array[i]); } } bigBox.push(result); bigBox.push(box); return bigBox; } module.exports.partition = partition; /** * Unique: Designed to take one arg(array), it will return a new array of all * elements with duplicates removed. Use indexOf from above . * * @arg {array} * * Usage: */ function unique(array){ var arr = []; for(var i = 0;i < array.length;i++){ if(_.indexOf(arr,array[i]) < 0){ arr.push(array[i]); } } return arr; }; module.exports.unique = unique; /** * map: Designed to take two args(collection, function), it past the function * over every element in the given collection. If collection is array * function(element,i,collection). If collection is Object function(value,key,collection) * Whatever the return value is will be saved in a new array. then it will return the array. * * Usage: */ _.map = function(collection, action){ let arr = []; if(Array.isArray(collection)){ for(var i = 0; i < collection.length; i++){ arr.push(action(collection[i], i, collection)); } }else { for(var key in collection){ arr.push(action(collection[key], key, collection)); } } return arr; }; module.exports.map = map; /** * pluck: Designed to take two args(array of objects, a property), it will an * array containing the value of property foe every elememt. * * @arg {array of objects, property} * * Usage: */ function pluck(array, prop){ return _.map(array, function(obj, i, arr) { return obj[prop]; }); }; module.exports.pluck = pluck; /** * contains: Designed to take two args(arrray, value), will return true if * value is found in array. Else it wiil return false. * * @arg {array, value} * * Usage: */ function contains(array, value){ return _.indexOf(array,value) >= 0 ? true : false ; }; module.exports.contains = contains; /** * every: Designed to take two args(collection,function), it will call the function * on every element of the collection. If collection is array function(element,index,collection) * If collection is object function(value, key, collection). So it will return true * if every element returns true from the function. If one returns false from the function * return false. * * @arg(collection,function) * * Usage: */ function every(collection, action){ if(!action){ if(_.filter(collection, function(element, i, collection){ return !element; }).length > 0){ return false; } }else if(action){ if(Array.isArray(collection)){ for(var e = 0; e < collection.length; e++){ if(action(collection[e], e, collection) === true){ }else { return false; } } } }else if(collection instanceof Object){ for(let key in collection){ if(action(collection[key], key, collection) === true){ }else{ return false; } } } return true; }; module.exports.every = every; /** *some: Designed to take args(collection,function), it will take the function and * pass over every element in the array. If collection is array function(element,i,collection) * , and if object function(value,key,collection). Next it will check if anyone of * the return are true if so it will return true. If all elements return false the the * return value is false. but if no function is given rtuen true if on element returns true. * * @arg(collection,function) * * Usage */ _.some = function(collection, action){ if(!action){ if( _.filter(collection, function(element){ return element; }).length > 0){ return true; }else { return false; } }else if(action){ if(Array.isArray(collection)){ for(var i = 0; i < collection.length; i++){ if(action(collection[i], i, collection) === false){ }else{ return true; } } }else{ for(var key in collection){ if(_.indexOf(Object.keys(collection), [key]) < 0){ return true; } } } return false; } module.exports.every = every; /** *reduce: Designed to take two arg(array,function,seed), it will call the function * over every element in array--function(previous result,element, array). the return value * of function will be used as previous result for next turn thru array. On the first * turn seed will be used as previous result. If no seed use array[0]/ first value as seed. * After final turn thur array return the value on the final function call. * *@arg{array,function,seed} * * Usage: */ _.reduce = function(array, action, seed){ let value; _.each(array, function(element, i, array){ if(seed === undefined && i === 0){ value = array[0]; }else if(i === 0){ value = action(seed, element, i); }else{ value = action(value, element, i); } }); return value; }; module.exports.reduce = reduce; /** *extend: Designed to have two arg(object1,object2) and could possibly have more objects. *First it will copy object2 properties to object2. If more propperties are passed in * copy them to object1 in the order they are passed. lastly return updated object1. * * @arg{Object1,object2} * * Usaage: */ _.extend = function(target, obj2){ var sources = [].slice.call(arguments, 1); sources.forEach(function (source) { Object.getOwnPropertyNames(source).forEach(function(propName) { Object.defineProperty(target, propName, Object.getOwnPropertyDescriptor(source, propName)); }); }); return target; }; module.exports.extend = extend;