Найти объект по заданному ключу c в глубоко вложенном объекте | Javascript - PullRequest
0 голосов
/ 15 апреля 2020

Какой самый чистый способ найти объект и вернуть его на основе идентификатора, если я не знаю, сколько вложенных объектов будет в моем объекте?

Допустим, у меня есть следующая структура:

  myObj = {
              "id": "5e6b8961ba08180001a10bb6",
              "children": [
                {
                  "id": "5e6b8961ba08180001a10bb7",
                  "refrenceId": "SEC-02986",
                  "children": [
                    {
                      "id": "5e58d7bc1bbc71000118c0dc"
                    },
                    {
                      "id": "5e58d7bc1bbc71000118c0dd",
                      "refrenceId": "SKU-00343"
                     },
                    {
                      "id": "5e590d571bbc71000118c102",
                      "refrenceId": "SKU-05290"
                    },
                    {
                      "id": "5e590df71bbc71000118c109",
                      "children": [
                        {
                          "id": "5e590df71bbc71000118c10a"
                        },
                        {
                          "id": "5e590df71bbc71000118c10b",
                          "refrenceId": "SKU-00444"
                    },
                    {
                      "id": "5e5cb9428ae591000177c0f6"
                    }
                  ]
                },
                {
                  "id": "5e81899f0bab450001dcfc1d",
                  "refrenceId": "SEC-03260"
                },
                {
                  "id": "5e81c4b51503860001f97f6c",
                  "refrenceId": "SEC-03267",
                  "children": [
                    {
                      "id": "5e8ad5175d374200014edb3a",
                      "refrenceId": "SEC-03409",
                      "children": [
                        {
                          "id": "5e8f28882d94c1000156bebe"
                        }
                      ]
                    },
                    {
                      "id": "5e8ad5175d374200014edb3c",
                       "refrenceId": "SEC-03410"
                    },
                    {
                      "id": "5e8f29082d94c1000156bec6",
                      "refrenceId": "SEC-03495"
                    }
                  ]
                }
              ]
            }

Предположим, я хочу найти объект с идентификатором "5e590df71bbc71000118c10b" и вернуть этот объект из вложенного объекта.

Я пытался использовать следующий код:

   function nodeHasChildren(children, id) {

    for (const child of children) {

      if (child.id === id) {

        if (Array.isArray(child.children) && child.children.length > 0) {
          return child;
        }
      }
      else {
          const result = nodeHasChildren(child.children, id);

        if (result !== undefined) {
          return result
        }
      }
    }
  }

console.log (nodeWithIdHasChildren (myObj, "5e590df71bbc71000118c10b"));

Ответы [ 2 ]

1 голос
/ 15 апреля 2020

Использовать простую рекурсию

function findDeepById(node, id) {
  if (node.id === id) return node;
  if (node.children) {
    for(const child of node.children){
      const match = findDeepById(child, id);
      if (match) return match;
    }
  }
}

const myObj = {
  "id": "5e6b8961ba08180001a10bb6",
  "children": [{
    "id": "5e6b8961ba08180001a10bb7",
    "refrenceId": "SEC-02986",
    "children": [{
        "id": "5e58d7bc1bbc71000118c0dc"
      },
      {
        "id": "5e58d7bc1bbc71000118c0dd",
        "refrenceId": "SKU-00343"
      },
      {
        "id": "5e590d571bbc71000118c102",
        "refrenceId": "SKU-05290"
      },
      {
        "id": "5e590df71bbc71000118c109",
        "children": [{
            "id": "5e590df71bbc71000118c10a"
          },
          {
            "id": "5e590df71bbc71000118c10b",
            "refrenceId": "SKU-00444"
          },
          {
            "id": "5e5cb9428ae591000177c0f6"
          }
        ]
      },
      {
        "id": "5e81899f0bab450001dcfc1d",
        "refrenceId": "SEC-03260"
      },
      {
        "id": "5e81c4b51503860001f97f6c",
        "refrenceId": "SEC-03267",
        "children": [{
            "id": "5e8ad5175d374200014edb3a",
            "refrenceId": "SEC-03409",
            "children": [{
              "id": "5e8f28882d94c1000156bebe"
            }]
          },
          {
            "id": "5e8ad5175d374200014edb3c",
            "refrenceId": "SEC-03410"
          },
          {
            "id": "5e8f29082d94c1000156bec6",
            "refrenceId": "SEC-03495"
          }
        ]
      }
    ]
  }]
};

function findDeepById(node, id) {

  if (node.id === id) return node;
  if (node.children) {
    for(const child of node.children){
      const match = findDeepById(child, id);
      if (match) return match;
    }
  }
}

console.log(findDeepById(myObj, "5e590df71bbc71000118c10b"));
0 голосов
/ 15 апреля 2020

Короче говоря, эта часть была самой большой проблемой:

if (child.id === id) {

    if (Array.isArray(child.children) && child.children.length > 0) {
      return child;
    }
  }

Вы нашли свой объект, зачем искать его детей?


ОРИГИНАЛЬНЫЙ ОТВЕТ / РАБОЧЕЕ РЕШЕНИЕ

Для начала вам нужно сделать исходный объект итеративным, потому что именно этого ожидает ваша функция. Я сделал это, просто сделав его массивом nodeHasChildren([myObj], ... при вызове функции. Затем, после некоторой очистки и исправления логики c, упомянутой выше, мы получаем это (добавлены соответствующие комментарии к приведенному ниже коду):

myObj = {
  "id": "5e6b8961ba08180001a10bb6",
  "children": [{
    "id": "5e6b8961ba08180001a10bb7",
    "refrenceId": "SEC-02986",
    "children": [{
        "id": "5e58d7bc1bbc71000118c0dc"
      },
      {
        "id": "5e58d7bc1bbc71000118c0dd",
        "refrenceId": "SKU-00343"
      },
      {
        "id": "5e590d571bbc71000118c102",
        "refrenceId": "SKU-05290"
      },
      {
        "id": "5e590df71bbc71000118c109",
        "children": [{
            "id": "5e590df71bbc71000118c10a"
          },
          {
            "id": "5e590df71bbc71000118c10b",
            "refrenceId": "SKU-00444"
          },
          {
            "id": "5e5cb9428ae591000177c0f6"
          }
        ]
      },
      {
        "id": "5e81899f0bab450001dcfc1d",
        "refrenceId": "SEC-03260"
      },
      {
        "id": "5e81c4b51503860001f97f6c",
        "refrenceId": "SEC-03267",
        "children": [{
            "id": "5e8ad5175d374200014edb3a",
            "refrenceId": "SEC-03409",
            "children": [{
              "id": "5e8f28882d94c1000156bebe"
            }]
          },
          {
            "id": "5e8ad5175d374200014edb3c",
            "refrenceId": "SEC-03410"
          },
          {
            "id": "5e8f29082d94c1000156bec6",
            "refrenceId": "SEC-03495"
          }
        ]
      }
    ]
  }]
}


function nodeHasChildren(children, id) {
  for (const child of children) {
    if (child.id === id) { 
          // solution found, no need to do anything else
          console.log("SOLUTION: ");
          return child;
    } else {
      // check if it has children and iterate over them recursively
      if (Array.isArray(child.children) && child.children.length > 0)
        var result = nodeHasChildren(child.children, id);
      // check if the result was found in children in the line above
      if (result != undefined)
        return result;
    }
  }
}
console.log(nodeHasChildren([myObj], "5e590df71bbc71000118c10b"));
console.log(nodeHasChildren([myObj], "5e8ad5175d374200014edb3c"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...