Package Exports
- deep-reduce
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (deep-reduce) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
deep-reduce
Reduce objects deeply, call reducer for every nested node in object tree. Use deepReduce
for
transforming/getting values from awfully nested objects. deepReduce
also traverse arrays.
Install
npm i deep-reduce
Usage
const deepReduce = require('deep-reduce')
const deepEqual = require('assert').deepEqual
// let nested leaf values be equal to their path, for demonstration purpose
let deepNestedObject = {
a: 'a',
b: { c: 'b.c' },
c: [
'c.0',
{
d: 'c.1.d',
e: [
'c.1.e.0'
]
}
]
}
// store all values which are strings to reduced[path].
let flattenStrings = (reduced, value, path) => {
if (typeof value === 'string') {
reduced[path] = value
}
return reduced
}
// the reduced value is returned
let reduced = deepReduce(deepNestedObject, flattenStrings)
// we should now have this object
deepEqual(reduced, {
'a': 'a',
'b.c': 'b.c',
'c.0': 'c.0',
'c.1.d': 'c.1.d',
'c.1.e.0': 'c.1.e.0'
})
Root object may be an array also:
deepReduce([{a: 1},{b: 2},{a: 3}], (r,v) => typeof v === 'number' ? r + v : r, 0)
// 6
Here is how you would collect all items of nested arrays at some specific path:
// we want to get contents from all packets
let transport = {
id: 'A8811',
packages: [
{
id: 'P100',
contents: [
{
id: 'R88',
name: 'resistor'
},
{
id: 'C99',
name: 'capacitor'
}
]
}, {
id: 'P101',
contents: [
{
id: 'C96',
name: 'coil'
}
]
}
]
}
let contents = deepReduce(transport, (reduced, value, path) => {
if (path.match(/packages\.\d+\.contents\.\d+$/)) {
// path is packages.n.contents.m
// item n in packages array
// item m in contents array
reduced.push(value)
}
return reduced
}, []) // start with an empty array
// [ { id: 'R88', name: 'resistor' },
// { id: 'C99', name: 'capacitor' },
// { id: 'C96', name: 'coil' } ]
API
deepReduce
takes 5 arguments. 2 mandatory and 3 optional:
deepReduce (
obj: object,
reducer: (reduced: any, value: any, path: string, root: object) => any,
reduced = {},
path = '',
thisArg = {}): any
Arguments
obj
Object to traverse.reducer
Function to call with every value inobj
-tree. See section below forreducer
function signature.reduced
Initial value ofreduced
passed toreducer
. Defaults to empty object{}
.path
Path to root, start traversing here. Nice to omit looping through parts ofobj
.Example:
deepReduce({ a: [1,2,3], b: { c: [3, 3] } }, (reduced, val) => reduced + val, 1, 'b.c') // only traverses b.c, returns 1 + 3 + 3 = 7
thisArg
Bound to reducer asthis
.
Arguments for reducer function
The reducer function is called with these arguments:
(reduced: any, value: any, path: string, root: object) => any
reduced
Initial or current reduced value.value
Value of current node.path
Path to current value.root
Root object passed todeepReduce
asobj
.
The reducer
should return the reduced
value.
Performance
deep-reduce
traverses every node of a 149 kb JSON in 10 milliseconds on a macbook air 2013 i5 1.3GHz, see test.js.
You can omit traversal of parts of the object tree with defining a start path
:
deepReduce(object, reducer, initialValue, 'start.at.this.path')
...which may give some performance gains.
Development
git clone https://github.com/arve0/deep-reduce
cd deep-reduce
npm start # watches index.ts and builds on any change
npm test # runs node test.js
License
MIT © 2017 Arve Seljebu