Home > Software engineering >  How can loop through nested array of objects for this in javascript?
How can loop through nested array of objects for this in javascript?

Time:11-25

const array = [
{ 
id: "1",
children: [],
messages:[1, 'Text'],
entry: "Father",
},

{
id: "2",
entry: "Mother",
children: [
    {entry: "John Jr"},
    {entry: "Steven Jr"},
    {entry: "Tim Jr"},
    ],
messages:[2, 'Text'],
}, 

{
id: "3",
entry: "Son",
children: [
    {entry: "XXX Jr"},
    {entry: "Steven Jr"},
    {entry: "Tim Jr"}
    ],
 messages:[3, 'Text'],
 },
]

So what I want here is, when I do the search "Tim". I want the output to be

Case 1: When I search for Tim, I should get the object with id: 2 and id: 3 because Tim is an entry matching in both the objects. so I want to return the entire id: 2 and 3 object in the same order.

{
id: "2",
entry: "Mother",
children: [
    {entry: "John Jr"},
    {entry: "Steven Jr"},
    {entry: "Tim Jr"},
    ],
messages:[2, 'Text'],
}, 

{
id: "3",
entry: "Son",
children: [
    {entry: "XXX Jr"},
    {entry: "Steven Jr"},
    {entry: "Tim Jr"}
    ],
 messages:[3, 'Text'],
 }

Case 2: When I search for John, I should get second object as

{
id: "2",
entry: "Mother",
children: [
    {entry: "John Jr"},
    ],
messages:[2, 'Text'],
}

Case 3: When I search for Steven, I should get id:2 and id:3 as

id: "2",
entry: "Mother",
children: [
    {entry: "John Jr"},
    {entry: "Steven Jr"},
    ],
messages:[2, 'Text'],
}, 

{
id: "3",
entry: "Son",
children: [
    {entry: "XXX Jr"},
    {entry: "Steven Jr"},
    ],
 messages:[3, 'Text'],
 }

I used .filter() to filter the top level but this isn't checking the children.

array.filter((item) => item.entry.toUpperCase().includes(text.toUpperCase())); 

Any help would be greatly appreciated as I'm totally lost with forEach here. Thanks in advance

CodePudding user response:

you can use Array.Filter , Array.some and splice the children array with index of the search entry object

const array = [{
    id: "1",
    children: [],
    messages: [1, 'Text'],
    entry: "Father",
  },

  {
    id: "2",
    entry: "Mother",
    children: [{
        entry: "John Jr"
      },
      {
        entry: "Steven Jr"
      },
      {
        entry: "Tim Jr"
      },
    ],
    messages: [2, 'Text'],
  },

  {
    id: "3",
    entry: "Son",
    children: [{
        entry: "XXX Jr"
      },
      {
        entry: "Steven Jr"
      },
      {
        entry: "Tim Jr"
      }
    ],
    messages: [3, 'Text'],
  },
];


let searchText = 'John';

let result = array.filter(el => {
  let i;
  let found = el.children.some((e, j) => {
    i = j;
    return e.entry.toLowerCase().indexOf(searchText.toLowerCase()) >= 0;
  });

  if (found)
    el.children = el.children.splice(0, i   1);

  return found;
});

console.log(result);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

const data=[{id:"1",children:[],messages:[1,"Text"],entry:"Father"},{id:"2",entry:"Mother",children:[{entry:"John Jr", children: [{entry: 'Bob', children: [{entry: 'Marvin'},{entry: 'Summer', children: [{entry: 'Batman'}, {entry: 'Robin'}]}]},{entry: 'Dave', children: [{entry: 'Sue'}, {entry: 'Sam'}]}]},{entry:"Steven Jr"},{entry:"Tim Jr"}],messages:[2,"Text"]},{id:"3",entry:"Son",children:[{entry:"XXX Jr", children: [{entry: 'Batman'}]},{entry:"Steven Jr"},{entry:"Tim Jr"}],messages:[3,"Text"]}];

function recurseChildren(children) {
  const arr = [];
  function loop(children) {
    for (const entry of children) {
      arr.push(entry.entry);
      if (entry.children) {
        loop(entry.children);
      }
    }
  }
  loop(children);
  return arr;
}

function finder(data, name) {

  // `filter` over the array
  return data.filter(obj => {

    // Recurse over the children array of all entries
    // to compile a list of names
    const names = recurseChildren(obj.children);

    // For each object check to see if
    // at least one of the entries in children
    // includes the name
    return names.some(entry => {
      return entry.includes(name);
    });

  });
}

console.log(finder(data, 'Tim'));
console.log(finder(data, 'John'));
console.log(finder(data, 'Steven'));
console.log(finder(data, 'Batman'));
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related