UNPKG

locutus

Version:

Locutus other languages' standard libraries to JavaScript for fun and educational purposes

47 lines (46 loc) 1.75 kB
function isScanReducer(value) { return typeof value === 'function'; } export function scan(values, initialOrReducer, maybeReducer) { // discuss at: https://locutus.io/elixir/scan/ // parity verified: Elixir 1.18 // original by: Kevin van Zonneveld (https://kvz.io) // note 1: Produces running accumulator states, similar to Elixir Enum.scan/2 and Enum.scan/3. // example 1: scan([1, 2, 3, 4], (acc, value) => Number(acc) + Number(value)) // returns 1: [1, 3, 6, 10] // example 2: scan([1, 2, 3], 10, (acc, value) => Number(acc) + Number(value)) // returns 2: [11, 13, 16] // example 3: scan([], 5, (acc, value) => Number(acc) + Number(value)) // returns 3: [] if (!Array.isArray(values)) { return []; } const hasInitial = typeof maybeReducer === 'function'; if (values.length === 0) { return []; } const out = []; if (hasInitial) { const reducer = maybeReducer; if (!isScanReducer(reducer)) { throw new TypeError('scan(): reducer must be a function'); } let accumulator = initialOrReducer; for (let i = 0; i < values.length; i++) { accumulator = reducer(accumulator, values[i], i, values); out.push(accumulator); } return out; } if (!isScanReducer(initialOrReducer)) { throw new TypeError('scan(): reducer must be a function'); } const reducer = initialOrReducer; let accumulator = values[0]; out.push(accumulator); for (let i = 1; i < values.length; i++) { accumulator = reducer(accumulator, values[i], i, values); out.push(accumulator); } return out; }