Je parcours un objet imbriqué d'objets, à la recherche d'un objet spécifique et si je le trouve, je fais des trucs. Je peux le faire fonctionner pour le premier nid, mais pour tout nid après cela, j'obtiens une valeur indéfinie.

let myObj = [{
    id: 1,
    children: [{
        id: 1.1,
        children: []
      },
      {
        id: 1.2,
        children: []
      }
    ]
  },
  {
    id: 2,
    children: [{
        id: 2.1,
        children: []
      },
      {
        id: 2.2,
        children: []
      }
    ]
  }
]


function addToObj(itemToAdd, parentId, obj) {

  for (let i = 0; i < obj.length; i++) {

    const item = search(obj[i], parentId);

    console.log(item); // undefined

    if (item) {
      item.children = item.children.concat(itemToAdd);
      break;
    }
  }

  function search(obj, id) {
    if (obj.id === id) {
      console.log(obj); // defined (obj with id of 2.1), but returns undefined?
      return obj;
    }

    for (let i = 0; i < obj.children.length; i++) {
      search(obj.children[i], id);
    }
  }

  return obj;
};

const itemToAdd = {
  id: 100,
}

addToObj(itemToAdd, 2.1, myObj);

La fonction de l'extrait de code ci-dessus parcourt l'objet à la recherche d'un élément spécifique. S'il trouve l'élément, il insérera un objet dans la propriété enfants de cet élément.

0
cup_of 17 mars 2019 à 10:29

2 réponses

Meilleure réponse

Vous devez utiliser la valeur de retour du récursif search : si elle existe, retournez-la :

for (let i = 0; i < obj.children.length; i++) {
  const possibleResult = search(obj.children[i], id);
  if (possibleResult) {
    return possibleResult;
  }
}
let myObj = [{
    id: 1,
    children: [{
        id: 1.1,
        children: []
      },
      {
        id: 1.2,
        children: []
      }
    ]
  },
  {
    id: 2,
    children: [{
        id: 2.1,
        children: []
      },
      {
        id: 2.2,
        children: []
      }
    ]
  }
]


function addToObj(itemsToAdd, parentId, obj) {

  for (let i = 0; i < obj.length; i++) {

    const item = search(obj[i], parentId);

    // first log here will be undefined, nothing found
    // second log here will find the object
    console.log('item', item);

    if (item) {
      item.children = item.children.concat(itemsToAdd);
      break;
    }
  }

  function search(obj, id) {
    if (obj.id === id) {
      console.log('obj', obj); // defined (obj with id of 2.1), but returns undefined?
      return obj;
    }

    for (let i = 0; i < obj.children.length; i++) {
      const possibleResult = search(obj.children[i], id);
      if (possibleResult) {
        return possibleResult;
      }
    }
  }

  return obj;
};

const itemToAdd = {
  id: 100,
}

addToObj(itemToAdd, 2.1, myObj);
1
CertainPerformance 17 mars 2019 à 07:32

Il y a deux problèmes dans le code

  • si (obj.id === id) est false alors en boucle vous ne retournez rien.
  • Vous devriez vérifier si obj.children existe avant la boucle.
let myObj = [
  {
    id: 1,
    children: [
    	{
      	id: 1.1,
        children: []
      },
      {
      	id: 1.2,
        children: []
      }
    ]
  },
  {
    id: 2,
    children: [
      {
        id: 2.1,
        children: []
      },
      {
      	id: 2.2,
        children: []
      }
    ]
  }
]

There are two problems in code:

 - List item

function addToObj(itemToAdd, parentId, obj) {

  for (let i=0;i<obj.length;i++) {

    const item = search(obj[i], parentId);

    console.log(item); // undefined

    if (item) {
      item.children = item.children.concat(itemToAdd);
      break;
    }
  }

  function search(obj, id) {
    if (obj.id === id) {
      console.log(obj); // defined (obj with id of 2.1), but returns undefined?
      return obj;
    }
    if(obj.children){
    
    for (let i=0;i<obj.children.length;i++) {
       let x = search(obj.children[i], id);
       if(x) return x;
      }
    }
  }

  return obj;
};

const itemToAdd = {
	id: 100,
}

addToObj(itemToAdd, 2.1, myObj);
1
Maheer Ali 17 mars 2019 à 07:43