Last active
June 14, 2021 05:20
-
-
Save JamieMason/4be6028de0608d5854c0 to your computer and use it in GitHub Desktop.
Perform a deeply recursive reduce on a JSON-encodable JavaScript Object hierarchy.
This file contains 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
/** | |
* Perform a deeply recursive reduce on a set of JSON, or a JSON-encodable Object hierarchy. | |
* | |
* @param {Array|Object} collection | |
* @param {Function} fn | |
* @param {*} memo | |
* @return {*} | |
*/ | |
function deepReduce(collection, fn, memo) { | |
/** | |
* @inner | |
* @param {*} value | |
* @param {String[]} path | |
* @return {*} | |
*/ | |
function iterator(value, path) { | |
var type = Object.prototype.toString.call(value); | |
memo = fn(memo, value, path); | |
if (type === '[object Array]') { | |
for (var i = 0, len = value.length; i < len; i++) { | |
iterator(value[i], path.concat(i)); | |
} | |
} else if (type === '[object Object]') { | |
for (var key in value) { | |
iterator(value[key], path.concat(key)); | |
} | |
} | |
return memo; | |
} | |
return iterator(collection, []); | |
} |
This file contains 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
/* | |
* Equivalent version in TypeScript | |
*/ | |
import { each, isArray, isObject } from 'lodash'; | |
export function deepReduce<In, Out>( | |
reducer: (accumulator: Out, value: any, path: Array<string | number>) => Out, | |
collection: In, | |
accumulator: Out, | |
): Out { | |
const iterator = <T>(value: T, paths: Array<string | number>) => { | |
accumulator = reducer(accumulator, value, paths); | |
if (isArray(value) || isObject(value)) { | |
each(value, (innerValue, innerKey) => | |
iterator<typeof innerValue>(innerValue, paths.concat(innerKey)), | |
); | |
} | |
}; | |
iterator<In>(collection, []); | |
return accumulator; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks mate. I was looking for something like this, saved my day!