kevinqdang
Version:
An npm functional programming library project
387 lines (358 loc) • 11.5 kB
JavaScript
// 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;
;