Skip to content

Instantly share code, notes, and snippets.

@stalniy
Created January 16, 2019 20:13
Show Gist options
  • Save stalniy/855f3de3115c8a89824370cb4d8bb5a7 to your computer and use it in GitHub Desktop.
Save stalniy/855f3de3115c8a89824370cb4d8bb5a7 to your computer and use it in GitHub Desktop.
Custom pick with support for arrays using asterisk
function get(object, path) {
const fields = Array.isArray(path) ? path : path.split('.')
let cursor = object
for (let i = 0; i < fields.length; i++) {
if (fields[i] === '*') {
// TODO: validation of cursor being an array
const newPath = fields.slice(i + 1)
return cursor.map(item => get(item, newPath))
} else {
cursor = cursor[fields[i]]
}
}
return cursor
}
function set(object, path, value) {
const fields = Array.isArray(path) ? path : path.split('.')
let cursor = object
let prevCursor
for (let i = 0; i < fields.length - 1; i++) {
const field = fields[i]
if (field === '*') {
const newPath = fields.slice(i + 1)
// TODO: validation of value being an array
const newValue = value.map((val, index) => set(cursor[index] || {}, newPath, val))
if (i > 0) {
prevCursor[fields[i - 1]] = newValue
} else {
return newValue
}
return object
} else {
prevCursor = cursor
cursor = cursor[field] = cursor[field] || {}
}
}
const lastField = fields[fields.length - 1]
if (Array.isArray(cursor)) {
cursor.forEach(item => item[lastField] = value)
} else {
cursor[lastField] = value
}
return object
}
function pick(object, paths) {
return paths.reduce((slice, path) => {
const value = get(object, path)
if (typeof value !== 'undefined') {
set(slice, path, value)
}
return slice
}, {})
}
const payload = {
title: 'test',
nested: {
field: 3,
another: 4
},
children: [
{
field: 1,
another: 2,
obj: {
title: 'test1',
nested: [
{ a: 1, c: 3 },
{ a: 3 }
]
}
},
{
field: 2,
another: 3,
obj: {
title: 'test2',
nested: [
{ a: 2, b: 2 }
]
}
}
]
}
console.log(pick(payload, [
'title',
'children.*.field', // asterisk mean "retrieve subpath from every array item. So, here we take `field` of every item inside `payload.children` array
'children.*.obj.nested.*.a'
]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment