Skip to content

Instantly share code, notes, and snippets.

@ughitsaaron
Last active March 21, 2017 20:15
Show Gist options
  • Save ughitsaaron/208fce52ab5380f2bb7b136a3fef61e1 to your computer and use it in GitHub Desktop.
Save ughitsaaron/208fce52ab5380f2bb7b136a3fef61e1 to your computer and use it in GitHub Desktop.
Common functions for lists using recursion…I did this for "funn" dot javascript
/**
* Just a collection of common list functions written recursively.
* https://jsbin.com/zupafusuco/1/edit?js,console
*/
/**
* callback function for iterating over a list
*
* @callback listCallback
* @param {any} value
* @param {number} index
* @param {array} list
*/
/**
* maps an array
* @param {array} list
* @param {listCallback} callback
* @param {array} result
* @returns {array}
*/
function map(list, fn, result = []) {
var mapped;
if (result.length === list.length) {
return result;
}
mapped = fn(list[result.length], result.length, list);
return map(list.slice(0), fn, result.concat(mapped));
}
/**
* filters an array
* @param {array} list
* @param {listCallback} callback
* @param {array} result
* @returns {array}
*/
function filter(list, fn, result = [], n = 0) {
var filtered;
if (n >= list.length) {
return result;
}
filtered = fn(list[n], n, list) ? result.concat(list[n]) : result.concat();
return filter(list.slice(0), fn, filtered, n + 1);
}
/**
* iterates over each item in an array
* @param {array} list
* @param {listCallback} callback
* @param {number} n
*/
function each(list, fn, n = 0) {
if (n + 1 <= list.length) {
fn(list[n], n, list);
return each(list, fn, n + 1);
}
}
/**
* callback function for reducing over a list
*
* @callback listCallback
* @param {any} value
* @param {any} result
* @param {number} index
* @param {array} list
*/
/**
* reduces a list to a value accumulated by iterating
* over each element
* @param {array} list
* @param {reduceCallback} callback
* @param {result} result
* @param {number} n
* @returns {any}
*/
function reduce(list, fn, result = null, n = 0) {
var reduced;
if (n >= list.length) {
return result;
}
reduced = fn(list[n], result, n, list);
return reduce(list.slice(0), fn, reduced, n + 1);
}
/**
* checks if an assertion is true for any element in a list
* @param {array} list
* @param {listCallback} callback
* @param {number} n
* @returns {boolean}
*/
function some(list, fn, n = 0) {
const assert = fn(list[n], n, list);
if (assert) {
return true;
}
if (n + 1 >= list.length) {
return false;
}
return some(list.slice(0), fn, n + 1);
}
/**
* checks if an assertion is true for every element in a list
* @param {array} list
* @param {listCallback} callback
* @param {number} n
* @returns {boolean}
*/
function every(list, fn, n = 0) {
const assert = fn(list[n], n, list);
if (!assert) {
return false;
}
if (n + 1 >= list.length) {
return true;
}
return every(list.slice(0), fn, n + 1);
}
const mapped = map([1, 2, 3], v => v + 1);
console.log({ mapped }) // => { mapped: [2, 3, 4] }
const filtered = filter([1, 2, 3, 4], v => v % 2 === 0);
console.log({ filtered }) // => { filtered: [2, 4] }
const eached = [];
each([1, 2, 3], v => eached.push(v));
console.log({ eached }) // => { eached: [1, 2, 3] }
const reduced = reduce(['foo', 'bar', 'baz'], (v, r) => r + v, '');
console.log({ reduced }) // => { reduced: 'foobarbaz' }
const isSome = some(['fizz', 'buzz', 'baz'], v => v.length === 3);
console.log({ isSome }); // => { isSome: true }
const isEvery = every(['foo', 'bar', 'buzz'], v => v.length === 3);
console.log({ isEvery }); // => { isEvery: false }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment