Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS: Find object by field in a complex Parent-Child Array

I use Javascript ES6 and have an issue.

I have an Array:

var commentList = [
   {'id': 1, text: 'A', children: [{'id': 2, text: 'B' }] },
   {'id': 4, text: 'asd', children: [] },
   {'id': 5, text: 'vx', children: [{'id': 7, text: 'xxss' }] },
   {'id': 8, text: 'ghfdh', children: [{'id': 15, text: 'I want to take this' }] },
   {'id': 10, text: 'A', children: [{'id': 18, text: 'Bsda' }] },
]

This is an Array with Parent - Child Structure. How can I get Exactly object {'id': 15, text: 'I want to take this' } if I just have ID only

I tried but not work

var object = commentList.find(o => o.id === 15) => undefined

like image 995
KitKit Avatar asked Nov 11 '18 11:11

KitKit


4 Answers

You could take an iterative and recursive approach by checking the id or taking the children.

const find = (array, id) => {
    var result;
    array.some(o => result = o.id === id ? o : find(o.children || [], id));
    return result;
};

var commentList = [{ id: 1, text: 'A', children: [{ id: 2, text: 'B' }] }, { id: 4, text: 'asd', children: [] }, { id: 5, text: 'vx', children: [{ id: 7, text: 'xxss' }] }, { id: 8, text: 'ghfdh', children: [{ id: 15, text: 'I want to take this' }] }, { id: 10, text: 'A', children: [{ id: 18, text: 'Bsda' }] }];

console.log(find(commentList, 15));
like image 135
Nina Scholz Avatar answered Oct 19 '22 07:10

Nina Scholz


You can use for...of to find the item recursively. If there's no item, the function will return undefined:

const find = (array = [], id) => {
  for (const item of array) {
    const result = item.id === id ? item : find(item.children, id);
    if(result) return result;
  }
};

const commentList = [{ id: 1, text: 'A', children: [{ id: 2, text: 'B' }] }, { id: 4, text: 'asd', children: [] }, { id: 5, text: 'vx', children: [{ id: 7, text: 'xxss' }] }, { id: 8, text: 'ghfdh', children: [{ id: 15, text: 'I want to take this' }] }, { id: 10, text: 'A', children: [{ id: 18, text: 'Bsda' }] }];

const result = find(commentList, 15);

console.log(result);
like image 29
Ori Drori Avatar answered Oct 19 '22 09:10

Ori Drori


I would extract the logic into a function and then iterate over the children array and return the one you requested (The first match).

var commentList = [
   {'id': 1, text: 'A', children: [{'id': 2, text: 'B' }] },
   {'id': 4, text: 'asd', children: [] },
   {'id': 5, text: 'vx', children: [{'id': 7, text: 'xxss' }] },
   {'id': 8, text: 'ghfdh', children: [{'id': 15, text: 'I want to take this' }] },
   {'id': 10, text: 'A', children: [{'id': 18, text: 'Bsda' }] },
]

const findChildById = (id, arr) => {
  const result = arr.find(o => o.id === id)
  if (result) return result
  for (const cm of arr) {
    const result = cm.children.find(o => o.id === id)
    if (result) return result
  }
}
console.log(findChildById(10, commentList))
like image 2
omri_saadon Avatar answered Oct 19 '22 08:10

omri_saadon


Following very simple and basic code should work for you. I assume that all id-s of all children elements in all arrays are unique. This code will find the first element that matches the id we are looking for;

var result = null;
var idToSearch = 15;
var i=0;
var j=0;

for(i=0; i<commentList.length; i++){
    var currentChildren = commentList[i].children;
    if(currentChildren && currentChildren.length > 0){
        for(j=0; j<currentChildren.length; j++){
            if(currentChildren[j].id === idToSearch){
                result=currentChildren[j];
                j=currentChildren.length;
                i=commentList.length;
            }
        }
    }
 }
like image 1
Tornike Shavishvili Avatar answered Oct 19 '22 09:10

Tornike Shavishvili