-1

I have object with subCategories property that contains objects where each contains subCategories as well.

const category = {
        categoryId: 123,
        name: "Cars",
        subCategories: [
          { categoryId: 32112, name: "BMW", subCategories: [] },
          {
            categoryId: 12321,
            name: "Audi",
            subCategories: [
              {
                categoryId: 21312,
                name: "Audi engine",
                subCategories: [
                  { categoryId: 1212, name: "engine-V-123", subCategories: [] },
                ],
              },
              { categoryId: 21112, name: "Audi wheels", subCategories: [] },
            ],
          },
          {...},
          {...}
        ],
      }

I need to write a function that will return a chain of indexes. For example, if I want to get engine-V-123 engine with id 1212, I should get:

".subCategories[1].subCategories[0].subCategories[0]"
  • Welcome to Stack Overflow! Please take the [tour] (you get a badge!) and read through the [help], in particular [*How do I ask a good question?*](/help/how-to-ask) Your best bet here is to do your research, [search](/help/searching) for related topics on SO, and give it a go. ***If*** you get stuck and can't get unstuck after doing more research and searching, post a [mcve] of your attempt and say specifically where you're stuck. People will be glad to help. – T.J. Crowder Jul 05 '21 at 14:58
  • similar [question](https://stackoverflow.com/q/67984311/12750399) and [answer](https://stackoverflow.com/a/67985517/12750399) – Nur Jul 05 '21 at 16:16

2 Answers2

1

Recursively generate path index by value from object.

const category = { categoryId: 123, name: "Cars", subCategories: [{ categoryId: 32112, name: "BMW", subCategories: [] }, { categoryId: 12321, name: "Audi", subCategories: [{ categoryId: 21312, name: "Audi engine", subCategories: [{ categoryId: 1212, name: "engine-V-123", subCategories: [] },], }, { categoryId: 21112, name: "Audi wheels", subCategories: [] },], },], }

function* extractPaths(data, value, path = "") {
    for (const key in data) {
        let $data = data[key], index = isFinite(+key) ? `[${key}]` : "." + key
        if (typeof $data == "object")
            yield* extractPaths($data, value, path + index);
        else if (value == $data)
            yield path
    }
}
console.log([...extractPaths(category, "engine-V-123")]);
Nur
  • 2,361
  • 2
  • 16
  • 34
0

Is this what you want?

const arr = [
  {
    categoryId: 1,
    name: "Cars",
    subCategories: [
      { categoryId: 21, name: "BMW", subCategories: [] },
      {
        categoryId: 22,
        name: "Audi",
        subCategories: [
          {
            categoryId: 31,
            name: "Audi engine",
            subCategories: [
              { categoryId: 41, name: "engine-V-123", subCategories: [] },
            ],
          },
          { categoryId: 32, name: "Audi wheels", subCategories: [] },
        ],
      },
    ],
  },
];

let isCategoryFound = false;

function searchIndex(arr, categoryId, name) {
  for (let i = 0; i < arr.length; i++) {
    let res = "";
    res += `.subCategories[${i}]`;
    const index = arr.findIndex(
      el => el.categoryId === categoryId && el.name === name
    );
    if (index !== -1) {
      isCategoryFound = true;
      //   return res;
    } else {
      res += searchIndex(arr[i].subCategories, categoryId, name);
    }

    if (isCategoryFound) {
      return res;
    }
  }
  return "";
}

const output = searchIndex(arr, 41, "engine-V-123");

console.log(output);
ikhvjs
  • 5,316
  • 2
  • 13
  • 36