This repository includes array, collection, object and other example manupulations using functional programming practices. Most of the excercises were mentioned here
To clone this repository
git clone https://github.com/ansaries/fp.git
Then run
npm install
I have used parcel for packaging and hot reload, so to run it use
parcel ./src/index.html
or just type in your console
npm start
- merge_with(fn) ⇒
Object
Merges Multiple Objects into one final Object with applied maping method
- memoize(fn) ⇒
function
Memoize a funtion based on its arguments
- compose(...fns) ⇒
function
Compose pipes all methods from right to left The return value of last(right) method will be injected into the arguments of next(left) method.
- flow(...fns) ⇒
function
Flow pipes all methods from left to right The return value of first(left) method will be injected into the arguments of next(right) method.
- pushItem(...args) ⇒
Array.<any>
Pushes an Item in Array and returns the Array with the new Item
- concatAll() ⇒
Array.<T>
Concat all arrays
- concatMap(fn) ⇒
Array.<T>
Concat all arrays while applying a Map function on each element of each array
- flip() ⇒
Array.<T>
Revese the array
- flatten(initial) ⇒
Array.<T>
Flattens a multi-dimensional array of any depth
- insert(item, i) ⇒
Array.<T>
Insert an item on a specified location and shift all of the rest to right.
- reject(mapFn)
Returns items that does not full fill the filterFn
- clist(...args) ⇒
Array.<any>
Converts arguments to array
- take(x, ar) ⇒
Array.<T>
Take a slice of array starting at 0 to x from an array ar
- range(N) ⇒
Array.<number>
Similar to range method of Python, creates an array of number from 1 to N
- frequencies() ⇒
function
Takes a sequence and counts how many times the elements appear in the sequence, returns a map.
- interleaveNfn(...args) ⇒
Array.<any>
Iterative Implementation of Interleave Time Complexity O(n) Interleaving is transposing two dimensional array and then concating or flattening it.
- interleaveFn(...args) ⇒
Array.<any>
Functional Implementation of Interleave Interleaving is transposing two dimensional array and then concating or flattening it.
- zip(...args) ⇒
Array.<any>
Transposes multi dimensional array
- transpose(...args) ⇒
Array.<any>
Transpose multi dimensional array
- zipWith(fn) ⇒
function
Accumulating the multi dimensional array using a accumulator method
- zipMapWith(fn, initialValue) ⇒
*
Takes a map function to apply on the array taken by composed function.
- zipDic(left, right) ⇒
Object
Creates an object from two arrays
- zipMap(left, right, mapFn) ⇒
Array.<(Object|any)>
Zips two arrays and maps out the output using the mapFn
- update(obj, prop, mapFn, val) ⇒
T
Updates a particular propery of an object using the mapFn function
- update_in(obj, propMap, mapFn, val) ⇒
T
Updates a particular property in a deep object tree using a map of keys and a map function.
Merges Multiple Objects into one final Object with applied maping method
Kind: global function
Param | Type |
---|---|
fn | function |
Example
merge_with(add, {"a": 1, "b": 2}, {"b": 2}) => {"a": 1, "b": 4}
Example
merge_with(sub, {"a": 1, "b": 2}, {"b": 2}) => {"a": 1, "b": 0}
// Similar to zipWith() for arrays
Memoize a funtion based on its arguments
Kind: global function
Summary:
Memoization requires that the passed function should be a pure-function
Returns:
function
- return a reusable function
Param | Type | Description |
---|---|---|
fn | function |
Pure Function |
Example
const summemo = memoize(add);
const submemo = memoize(sub);
summemo(4, 6); // Computes 4 + 6 => 10
submemo(4, 6); // Computes 4 - 6 => -2
summemo(4, 6); // Does not compute, rather return from cash => 10
submemo(4, 6); // Does not compute, rather return from cash => -2
Compose pipes all methods from right to left The return value of last(right) method will be injected into the arguments of next(left) method.
Kind: global function
Returns: function
-
Returns a function which takes any argument
Param | Type | Description |
---|---|---|
...fns | Array.<function()> |
one or more functions as arguments to apply composedly |
Example
// Suppose you want to get Grand Total of a cart after Tax and Discount.
var getGrandTotal = compose(Math.round, add);
// grandTotal = subTotalCart + Vat + Gst - Discount
var grandTotal = getGrandTotal(
subTotalCart,
VAT(subTotalCart),
GST(subTotalCart),
negative(Discount(subTotalCart))
);
// Suppose for no EU customer the Vat does not apply
var nonUsGrandTotal = getGrandTotal(
subTotalCart,
GST(subTotalCart),
negative(Discount(subTotalCart))
);
Flow pipes all methods from left to right The return value of first(left) method will be injected into the arguments of next(right) method.
Kind: global function
Returns: function
-
Returns a function which takes any argument
Param | Type | Description |
---|---|---|
...fns | Array.<function()> |
one or more functions as arguments to apply composedly |
Example
// Suppose you want to get Grand Total of a cart after Tax and Discount.
var getGrandTotal = flow(add, Math.round);
// grandTotal = subTotalCart + Vat + Gst - Discount
var grandTotal = getGrandTotal(
subTotalCart,
VAT(subTotalCart),
GST(subTotalCart),
negative(Discount(subTotalCart))
);
// Suppose for no EU customer the Vat does not apply
var nonUsGrandTotal = getGrandTotal(
subTotalCart,
GST(subTotalCart),
negative(Discount(subTotalCart))
);
Pushes an Item in Array and returns the Array with the new Item
Kind: global function
Param | Type |
---|---|
...args | * |
Concat all arrays
Concat all arrays while applying a Map function on each element of each array
Kind: global function
Param | Type |
---|---|
fn | function |
Example
[[1, 2, 3], [4, 5], [6]].concatMap(add); // => [1,3,5,7,9,11]
Revese the array
Flattens a multi-dimensional array of any depth
Kind: global function
Param | Type |
---|---|
initial | * |
Example
[[1],[[[2]],[[[[[3]]]]]].flatten(); // => [1,2,3,4]
Insert an item on a specified location and shift all of the rest to right.
Kind: global function
Param | Type | Default |
---|---|---|
item | T |
|
i | number |
0 |
Example
[1,3,4,5,6].insert(2,1) => [1,2,3,4,5,6]
Returns items that does not full fill the filterFn
Kind: global function
Param | Type | Description |
---|---|---|
mapFn | function |
(x: any, i: number) => Array |
Converts arguments to array
Kind: global function
Returns: Array.<any>
-
Return an Array of type any
Param | Type | Description |
---|---|---|
...args | any |
Arguments of type any |
Example
clist(1,2,3,4,5); => [1,2,3,4,5]
Take a slice of array starting at 0 to x from an array ar
Kind: global function
Param | Type |
---|---|
x | number |
ar | Array.<any> |
Similar to range method of Python, creates an array of number from 1 to N
Kind: global function
Param | Type |
---|---|
N | number |
Example
range(10) => [1,2,3,4,5,6,7,8,9,10]
Takes a sequence and counts how many times the elements appear in the sequence, returns a map.
Kind: global function
Example
frequencies()("aabcbcac"); => {'a': 3, 'c': 3, 'b': 2}
frequencies()([1, 2, 2, 2]); => {1: 1, 2: 3}
Iterative Implementation of Interleave Time Complexity O(n) Interleaving is transposing two dimensional array and then concating or flattening it.
Kind: global function
Param | Type |
---|---|
...args | * |
Example
interleaveNfn([1, 2, 3], [4, 5, 6], [7, 8, 9]); //=> [1,4,7,2,5,8,3,6,9]
// Implementation is as follows:
function interleaveNfn(...args) {
const arr = [];
const length = args.length;
const inerLength = args[0].length;
for (let i = 0; i < length; i++)
for (let j = 0; j < inerLength; j++) {
arr.push(args[j][i]);
}
return arr;
}
Functional Implementation of Interleave Interleaving is transposing two dimensional array and then concating or flattening it.
Kind: global function
Param | Type |
---|---|
...args | * |
Example
interleaveFn([1, 2, 3], [4, 5, 6], [7, 8, 9]); //=> [1,4,7,2,5,8,3,6,9]
// Implementation is as follows:
export function interleaveFn(...args) {
// Simple Declarative way
// transpose([1,2,3],[4,5,6],[7,8,9]) => [[1,4,7],[2,5,8],[3,6,9]]
// [[1,4,7],[2,5,8],[3,6,9]].concatAll() => [1,4,7,2,5,8,3,6,9]
return transpose(...args).concatAll();
}
Transposes multi dimensional array
Kind: global function
Param | Type |
---|---|
...args | * |
Example
[[1,2,3], [4,5,6], [7,8,9]] => [[1,4,7],[2,5,8],[3,6,9]]
Example
[[1, 2, 3], [4, 5, 6]].zip() => [[1, 4], [2, 5], [3, 6]]
// Implementation is as follows:
function zip(...args) {
return args.reduce((p, c, i) => {
if (p.length <= 0)
// [1,2,3] => [[1],[2],[3]]
return c.reduce((cp, cc) => cp.pushItem([cc]), []);
else
// [[1],[2],[3]] => [[1,4,...], [2,5,...],[3,6,...]]
return p.map((x, i) => x.pushItem(c[i]));
}, []);
}
Transpose multi dimensional array
Kind: global function
Param | Type | Description |
---|---|---|
...args | Array.<any> |
multiple array arguments |
Example
transpose([1,2,3], [4,5,6], [7,8,9]) => [[1,4,7],[2,5,8],[3,6,9]]
// Similar to
[[1, 2, 3], [4, 5, 6]].zip() => [[1, 4], [2, 5], [3, 6]]
Accumulating the multi dimensional array using a accumulator method
Kind: global function
Summary:
Usefull in creating Totals for Tables, or applying discounts on each or any column etc.
Returns:
function
- Returns a method which accumulates its arguments
Param | Type | Description |
---|---|---|
fn | function |
Accumulator function (x: any,y: any) => any Takes two argument x: elem of previous array y: elem of next array |
Example
var getTotals = zipWith(add);
var subTotal = getTotals([1, 2, 3], [4, 5, 6], [7, 8, 9]);
// [[1,2,3], [4,5,6], [7,8,9]] => [12,15,18]
Takes a map function to apply on the array taken by composed function.
Kind: global function
Summary:
Uses Partial Application to first create a mapper function and then calls a reusable apply function on an array.
Param | Type | Description |
---|---|---|
fn | function |
(x:any,y:any) => any |
initialValue | * |
Example
// Take an example of a cart like below:
const cart=[
{"name":"Biscuits", "type":"regular", "category":"food", "price": 2.0},
{"name":"Monitor", "type":"prime", "category":"tech", "price": 119.99},
{"name":"Mouse", "type":"prime", "category":"tech", "price": 25.50},
{"name":"dress", "type":"regular", "category":"clothes", "price": 49.90},
]
const subTotal = zipMapWith(sumOfPrice,0);
// where sumOfPrice works as a reducer function and then use subTotal as
const subTotalCart = subTotal(cart); => 197
// The sumOfPrice will reduce the prices of all items of cart array.
// Lets say we have another partial application for applyDiscount then:
// Apply Discount of 10% on clothing catagory
const discountedCart = applyDiscount(10, mul)("category","clothes");
// Now reuse the subTotal method to calculate the discounted cart.
const subTotalDiscounted = subTotal(discountedCart); => 192
/////////////////////////////////////////////////////////////////////////////
Creates an object from two arrays
Kind: global function
Summary:
Create keys from first array and values from second. First array has to be array of strings, second array could be anything. However the final object will have only as many keys as the length of left array.
Param | Type |
---|---|
left | Array.<string> |
right | Array.<any> |
Example
// Create keys from first array and values from second.
// First array has to be array of strings
zipDic(['a','b','c'],[1,2,3]) => {a:1, b:2, c:3}
Zips two arrays and maps out the output using the mapFn
Kind: global function
Param | Type | Description |
---|---|---|
left | Array.<any> |
|
right | Array.<any> |
|
mapFn | function |
(x: any, y:any) => Array |
Example
// Zips two arrays to a single array.
zip([1,2,3],[4,5,6], add) => [5,7,9]
Example
// Zips two arrays to array of objects depending on map function.
zip([1,2,3],[4,5,6], (x,y,i) => ({a:x, b:y}); => [{a:1, b:4},{a:2, b:5},{a:3, b:6}]
Updates a particular propery of an object using the mapFn function
Kind: global function
Returns: T
-
Same object with value of destination key updated using maping function.
Param | Type | Description |
---|---|---|
obj | T |
Souce Object of Type T |
prop | string |
property name string |
mapFn | function |
Mapping Function |
val | * |
Assigning value |
Example
// Source Object
var bob = { name: 'bob', hp: 3 };
//add 2 to to hp property of bob
// Applying mapping as addition function
// const add = (x,y) => x+y;
update(bob, 'hp', add, 2); // => {"name": "bob", "hp": 5}
Updates a particular property in a deep object tree using a map of keys and a map function.
Kind: global function
Summary:
Use it to update a particular deeply nested field of an object. For example it can be used to apply tax on an accessory of an item in a cart.
Returns:
T
- Same object with value of destination key updated using maping function.
Param | Type | Description |
---|---|---|
obj | T |
Souce Object of Type T |
propMap | Array.<string> |
Array of strings representing the property depth |
mapFn | function |
Mapping Function |
val | * |
Assigning value |
Example
// Source Object
var a = { a: 1, b: { c: 2, d: { e: 10 } } };
// Applying mapping as multiplication function
// const mul = (x,y) => x*y;
update_in(a, ['b', 'd', 'e'], mul, 0.9); // => {"a": 1, "b": {"c": 2, d: {e: 9}}}
Its personal level excercise, I tried to use vanilla to show values on Browser in a very weired manner. Just use it for inspiration, all methods and examples are not recommended for production.