I have arrays of deeply nested objects. I would like to write a function to extract arbitrary child objects from these arrays. In some cases values of nested properties are values and objects, in other cases they are arrays.
Examples of arrays are below:
[{parent: {level1: {level2: 'data'}}}]
[{parent: {level1: [{level2: {...}}, {level2: {...}}, {level2: {...}}]}}]
[{parent: {level1: [{level2: {level3: 'data'}}, {level2: {..}}, {level2: {..}}]}}]
Calling extraction function on such an array should result in an array of objects that we're interested in.
Examples of calling the function and its results for the example arrays above:
extractChildren(source, 'level2') = [{level2: 'data'}]
extractChildren(source, 'level2') = [{level2: {...}, level2: {...}, level2: {...}]
extractChildren(source, 'level3') = [{level3: 'data'}]
Is there a concise way to achieve this with lodash
or I should use regular JavaScript to iterate through properties?
P.S. Think of it as equivalent of XPath select all nodes with the name "nodename"
I hope, it helps:
'use strict';
let _ = require("lodash");
let source = [{parent: {level1: [{level2: {level3: 'data'}}, {level2: {}}, {level2: {}}]}}];
function extractChildren(source, specKey) {
let results = [];
let search = function(source, specKey) {
_.forEach(source, function(item) {
if (!!item[specKey]) {
let obj = {};
obj[specKey] = item[specKey];
results.push(obj);
return;
}
search(item, specKey);
});
};
search(source, specKey);
return results;
};
console.log(extractChildren(source, 'level3'));
// [ { level3: 'data' } ]
From this question:
Elegant:
function find_obj_by_name(obj, key) {
if( !(obj instanceof Array) ) return [];
if (key in obj)
return [obj[key]];
return _.flatten(_.map(obj, function(v) {
return typeof v == "object" ? find_obj_by_name(v, key) : [];
}), true);
}
Efficient:
function find_obj_by_name(obj, key) {
if( !(obj instanceof Array) ) return [];
if (key in obj)
return [obj[key]];
var res = [];
_.forEach(obj, function(v) {
if (typeof v == "object" && (v = find_obj_by_name(v, key)).length)
res.push.apply(res, v);
});
return res;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With