-
Notifications
You must be signed in to change notification settings - Fork 11
/
property-value.js
45 lines (40 loc) · 1.3 KB
/
property-value.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
function valueAt(obj, path) {
var parts = path.split('.')
var prop = parts.shift()
if (isPrimitive(obj[prop])) {
return [obj[prop]]
} else if (isObject(obj[prop])) {
return valueAt(obj[prop], parts.join('.'))
} else if (isPrimitiveArray(obj[prop])) {
return obj[prop].reduce(function(values, val) {
if (values.indexOf(val) < 0) values.push(val)
return values
},[])
} else if (isObjectArray(obj[prop])) {
return obj[prop].reduce(function(values, item) {
var vals = valueAt(item, parts.join('.'))
vals.reduce(function(sum, key) {
if (sum.indexOf(key) < 0) sum.push(key)
return sum
}, values)
return values
}, [])
} else {
throw new TypeError('property path: "'+ path + '" not valid in your data at object: '+ JSON.stringify(obj))
}
}
function isPrimitive(val) {
return typeof val === 'string' || typeof val === 'number'
|| typeof val === 'boolean'
}
function isPrimitiveArray(val) {
return Array.isArray(val) && val.length > 0 && isPrimitive(val[0])
}
function isObject(val) {
// `typeof [{id: 1}]` returns value object so frst negate array
return !Array.isArray(val) && typeof val === 'object'
}
function isObjectArray(val) {
return Array.isArray(val) && val.length > 0 && typeof val[0] === 'object'
}
module.exports = valueAt