Created
July 20, 2016 03:32
-
-
Save hunan-rostomyan/0386d252b5206e84bb3e70df71d7fcce to your computer and use it in GitHub Desktop.
Scan (prefix sum, cumulative sum, inclusive scan) in JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// What does scan*(id, op, arr) do? | |
// | |
// Given an identity element `id`, a binary associative | |
// operator `op`, and a list `arr`, returns a list of the | |
// same size where each item in that list is the op-sum | |
// of all previous items. | |
// | |
// E.g. sum(0, +, [3, 4]) => [(0 + 3), (3 + 4)] | |
// E.g. sum(1, *, [2, 5]) => [(1 * 2), (2 * 5)] | |
// Helpers | |
function cons(x, lst) {return lst.concat([x]);} | |
function first(list) {return list[0];} | |
function last(list) {return list.slice(-1)[0];} | |
function rest(list) {return list.slice(1);} | |
function add(a, b) {return a + b;} | |
function mult(a, b) {return a * b;} | |
// Variant 1 (Imperative) | |
function scanImperative(id, op, arr) { | |
var ret = [], i; | |
for (i = 0; i < arr.length; i++) { | |
ret = cons(op(arr[i], (last(ret) || id)), ret); | |
} | |
return ret; | |
} | |
// Variant 2 (Recursive) | |
function scanRecursive(id, op, arr) { | |
function helper(toRet, arr) { | |
if (!arr.length) {return toRet;} | |
var prev = (last(toRet) || id); | |
return helper(cons(op(first(arr), prev), toRet), rest(arr)); | |
} | |
return helper([], arr); | |
} | |
// Variant 3 (Functional) | |
function scanFunctional(id, op, arr) { | |
return arr.reduce(function(prev, cur) { | |
return cons(op(cur, (last(prev) || id)), prev); | |
}, []); | |
} | |
// Usage | |
var scan = scanFunctional; // choose your favorite version | |
scan(0, add, [2, 3, 4]); //=> [(0 + 2), (2 + 3), (5 + 4)] = [2, 5, 9] | |
scan(1, mult, [2, 3, 4]); //=> [(1 * 2), (2 * 3), (6 * 4)] = [2, 6, 24] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment