Reputation: 174
I have array of nested object. I have to check the property of key object and return its value. I have done it using the for loop and checking with children property exist or not. But I think it is not optimal way to do it. what will be most optimal way to do it. Here is the code array of object data. I have to get text for the id 121.
var abc = [
{
id: 1,
text: 'One',
children: [
{id: 11, text: 'One One'},
{id: 12, text: 'One two',
children: [ {id: 121, text: 'one two one'} ]}
]
},
{
id: 2,
text: 'two'
}
];
My approach is very specific to this problem. Here it is
for(var val of abc){
if(val.id == 121){
console.log('in first loop',val.text);
break;
}
if(Array.isArray(val.children)){
for(var childVal of val.children) {
if(childVal.id == 121){
console.log('in first child', childVal.text);
break;
}
if(Array.isArray(childVal.children)){
for(var nextChild of childVal.children){
if(nextChild.id == 121){
console.log('in next child', nextChild.text);
break;
}
}
}
}
}
}
Upvotes: 1
Views: 106
Reputation: 206344
Given your Nodes have nested Nodes in a children
property, using a recursion and Array.prototype.find() to find a Node by ID:
const getNode = (a, id, c = 'children', r) => {
const rec = a => a.find(o => o.id==id && (r=o) || c in o && rec(o[c]));
return rec(a) && r;
};
const abc = [{id: 1, text: 'One', children: [{id: 11, text: 'One one'}, {id: 12, text: 'One two', children: [{id: 121, text: 'One two one'}]}]}, {id: 2, text: 'Two' }];
console.log( getNode(abc, 121)?.text ); // One two one
Upvotes: 0
Reputation: 386680
You could take an approach with a short circuit and return a result from a wanted property.
const
getValue = (object, key, id) => {
const search = o => {
if (!o || typeof o !== 'object') return;
if (o.id === id) return { value: o[key] };
var value;
Object.values(o).some(p => value = search(p));
return value;
};
return search(object)?.value;
};
var array = [{ id: 1, text: 'One', children: [{ id: 11, text: 'One One' }, { id: 12, text: 'One two', children: [{ id: 121, text: 'one two one' }] }] }, { id: 2, text: 'two' }];
console.log(getValue(array, 'text', 121));
console.log(getValue(array, 'text', 3000));
Upvotes: 1
Reputation: 122077
You could create recursive function using for...in
loop that returns the matched object and then you can get its text property.
var abc = [{"id":1,"text":"One","children":[{"id":11,"text":"One One"},{"id":12,"text":"One two","children":[{"id":121,"text":"one two one"}]}]},{"id":2,"text":"two"}]
function getProp(data, key, value) {
let result = null;
for (let i in data) {
if (typeof data[i] == 'object' && !result) {
result = getProp(data[i], key, value)
}
if (i == key && data[i] == value) {
result = data
}
}
return result;
}
const result = getProp(abc, 'id', 121)
console.log(result)
Upvotes: 2