1

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;
         }

       }

       }
   }

  }

}

2
  • " I have done it using..." - Please add your approach. And add more details to your "requirement" or at least an example with a given in- and output. Commented Apr 1, 2020 at 7:39
  • updated with my approach. Commented Apr 1, 2020 at 8:02

3 Answers 3

2

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)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for this recurring approach. I don't know if we can utilize ES6 features here. Just a thought
1

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));

4 Comments

nice !!! I think just need to remove ? from return search(object)?.value;
no, without optional chaining operator ?., you would need an assignemnt of the result and check if the result is truthy and then get value from it.
I run the code and it throw the syntax error for the same
@Abhishek are you using IE?
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.