Skip to content

Instantly share code, notes, and snippets.

@mika76
Forked from goldhand/compose.js
Created March 6, 2021 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mika76/00f2918f4d439aa6d4873162d04fcdde to your computer and use it in GitHub Desktop.
Save mika76/00f2918f4d439aa6d4873162d04fcdde to your computer and use it in GitHub Desktop.
ATA JS (Day 2) Functions - Daily Assignment Solutions reviewed in class
const reduce = require("./reduce");
/**
* Performs right-to-left function composition. The rightmost function may have
* any arity; the remaining functions must be unary.
* compose(f, g)(x) >> f(g(x))
*
* @example
* const doubleNegative = compose(x => x * -1, x => x * 2);
* doubleNegative(5); // -10
*
* @param {Array<Function>} fns Array of functions to compose
* @return {Function}
*/
const compose = (...fns) => {
function myReduceFn (acc, fn) {
return fn(acc);
}
function myReturnedFn (arg) {
const result = reduce(myReduceFn, arg, fns.reverse());
return result;
}
return myReturnedFn;
};
module.exports = compose;
/**
* Returns a curried equivalent of the provided function but can also accept
* multiple arguments at one time.
*
* @example
* const sum = curry((a, b) => a + b);
* const addFive = sum(5);
* addFive(10); //=> 15
*
* @param {Function} fn The function to curry.
* @return {Function} A new, curried function.
*/
const curry = (fn) => function curriedFn (...args) {
if (args.length < fn.length) {
return function (...curriedArgs) {
const nextargs = args.concat(curriedArgs);
return curriedFn(...nextargs);
};
}
return fn(...args);
};
module.exports = curry;
const curry = require("./curry");
/**
* Takes a predicate and an array, and returns a new array containing the
* members of the given array which satisfy the given predicate.
*
* @example
* filter(x => x > 0, [-2, -1, 0, 1, 2]); //=> [1, 2]
*
* @param {Function} predicate Function that will be passed a value from the
* given array and should return a boolean.
* @param {Array<*>} arr
* @return {Array<*>}
*/
const filter = (predicate, arr) => {
const result = [];
for (let i = 0; i < arr.length; i++) {
if (predicate(arr[i])) {
result.push(arr[i]);
}
}
return result;
};
module.exports = curry(filter);
const curry = require("./curry");
/**
* Takes a function and an array, applies the function to each of the array's
* values, and returns an array of the same shape.
*
* @example
* map(x => x + 1, [1, 2, 3]); // [2, 3, 4]
*
* @param {Function} fn
* @param {Array<*>} arr
* @return {Array<*>}
*/
const map = (fn, arr) => {
const result = [];
for (let i = 0; i < arr.length; i++) {
const processedItem = fn(arr[i]);
result.push(processedItem);
}
return result;
};
module.exports = curry(map);
const memoize = (fn) => {
const cache = {};
// cache[2] = foo(2);
return (arg) => {
// const cache = {};
if (cache.hasOwnProperty(arg)) {
return cache.arg;
}
const result = fn(arg);
cache[arg] = result;
return result;
};
};
module.exports = memoize;
const curry = require("./curry");
/**
* Returns a single item by iterating through the list, successively calling the
* iterator function and passing it an accumulator value and the current value
* from the array, and then passing the result to the next call.
*
* @example
* reduce((acc, x) => acc - x, 0, [1, 2, 3]) // => (((0 - 1) - 2) - 3) = -6
*
* @param {Function} fn The iterator function. Receives two values, the
* accumulator and the current element from the array.
* @param {*} acc The accumulator value.
* @param {Array<*>} arr The array to iterate over
* @return {*} The final, accumulated value.
*/
const reduce = (fn, acc, arr) => {
let processed = acc;
for (let i = 0; i < arr.length; i++) {
processed = fn(processed, arr[i]);
}
return processed;
};
module.exports = curry(reduce);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment