Przeszukiwanie zagnieżdżonego obiektu / json

0

Cześć, napisałem sobie prostą funkcję do przeszukiwania tablicy. Funkcja ma za zadane znaleźć element o odpowiednim ID w tablicy z zagnieżdżonymi childami. O ile wynik w konsoli pokazywany jest w prawidłowy sposób, to return działa tylko w przypadku elementów, które nie są zagnieżdżone w childrenie. Te zagnieżdżone zawsze zwracają undefined. Zakładam, że problem leży w zagnieżdżeniu funkcji w funkcji. Testowałem różne sposoby, ale nie mogę znaleźć rozwiązania tego problemu, bardzo proszę o pomoc lub wskazówki.

function testowa(obj, find_id)
{

  if (obj.id == find_id) return obj.id;

  for (var k in obj)
  {
    if (obj[k].children)
    {
      if (obj[k].id == find_id)
      {
        console.log(obj[k].id);
        return obj[k].id;
      }
      else
      {
        testowa(obj[k].children, find_id);
      }

    }
    else
    {
      if (obj[k].id == find_id)
      {
        console.log(obj[k].id);
        return obj[k];
      }
    }
  }

}

[
  {
    "name": "Item 1",
    "id": 1
  },
  {
    "name": "Item 2",
    "id": 2
  },
  {
    "name": "Item 3",
    "id": 3,
    "children": [
      {
        "name": "Item 4",
        "id": 4
      },
      {
        "name": "Item 5",
        "id": 5,
        "children": [
          {
            "name": "Item 6",
            "id": 6
          }
        ]
      }
    ]
  }
]

4

Masz rekurencję, ale tego co zwraca wywołanie rekurencyjne nie łapiesz w żaden sposób, więc to nie może działać. Bez wgłębiania się w kod obstawiam, że zmiana na return testowa(obj[k].children, find_id); może zadziałać.

0
szatkus1 napisał(a):

Masz rekurencję, ale tego co zwraca wywołanie rekurencyjne nie łapiesz w żaden sposób, więc to nie może działać. Bez wgłębiania się w kod obstawiam, że zmiana na return testowa(obj[k].children, find_id); może zadziałać.

Tak, dokładnie, dodanie returna naprawiło sytuację. Ech, dziękuję za pomoc :)

2

masz duplikację logiki i przypuszczalnie buga (bo raz zwracasz id a raz obiekt - to w końcu co chcesz zwrócić? Zakładam, że obiekt, bo id jest już dane).

No i 3 razy sprawdzasz ten sam warunek czy id jest zgodne z szukanym. Mimo, że raz by wystarczyło na szczycie funkcji testowa. Skoro i tak wywołujesz ją rekurencyjnie.

No i for...in nie służy do iteracji po tablicy, tylko do iteracji po kluczach obiektu. Przez przypadek działa (jeśli w tablicy nie ma żadnych kustomowych właściwości), ale do tablicy lepiej użyć np. for... of.

Ogólnie tę funkcję dałoby się przepisać tak:

function testowa(obj, find_id) {
  if (obj.id == find_id) return obj;
  if (obj.children) {
    for (const item of obj.children) {
      const result = testowa(item, find_id);
      if (result) return result;
    }
  }
}

console.log(testowa({children: arr}, 6)); 

gdzie arr to te dane, które wpisałeś w pierwszym poście

const arr = [
  {
    "name": "Item 1",
    "id": 1
  },
  {
    "name": "Item 2",
    "id": 2
  },
  ........ i dalej

1 użytkowników online, w tym zalogowanych: 0, gości: 1