-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathflatten.js
58 lines (50 loc) · 1.55 KB
/
flatten.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
var debug = require('debug')('keypather:expand')
var defaults = require('101/defaults')
var exists = require('101/exists')
var isObject = require('101/is-object')
var keyRequiresBracketNotation = require('./lib/key-requires-bracket-notation')
module.exports = function flatten (obj, opts) {
debug('flatten %O %O', obj, opts)
opts = exists(opts) ? opts : {}
if (typeof opts === 'string') {
opts = { delimeter: opts }
}
defaults(opts, {
delimeter: '.',
dest: {}
})
var isArray = Array.isArray(obj)
var keys = Object.keys(obj)
return keys.reduce(function (flat, key) {
var val = obj[key]
// convert key to bracket key if necessary
var isBracketKey = false
if (isArray && /^[0-9]+$/.test(key)) {
// obj is array, use bracket key
isBracketKey = true
key = '[' + key + ']'
} else if (keyRequiresBracketNotation(key)) {
// key starts with invalid char for dot key, use bracket key
isBracketKey = true
key = '["' + key + '"]'
}
// create keypath
var keypath = exists(opts.parentKeypath)
? [ opts.parentKeypath, key ].join(isBracketKey ? '' : opts.delimeter)
: key
// check if value is flattenable
if (Array.isArray(val) || isObject(val)) {
// value is flattenable, continue flattenning
flatten(val, {
delimeter: opts.delimeter,
parentKeypath: keypath,
dest: flat
})
} else {
// value is not flattenable, set flat key
flat[keypath] = val
}
// return flattenned object
return flat
}, opts.dest)
}