Search code examples
javascriptarraysfunctiontreeview

Find all children's key by specific key in a deep nested array object


const data = [
  {
    title: '0-0',
    key: '0-0',
    children: [
      {
        title: '0-0-0',
        key: '0-0-0',
        children: [
          { title: '0-0-0-0', key: '0-0-0-0' },
          { title: '0-0-0-1', key: '0-0-0-1' },
          { title: '0-0-0-2', key: '0-0-0-2' },
        ],
      },
      {
        title: '0-0-1',
        key: '0-0-1',
        children: [
          { title: '0-0-1-0', key: '0-0-1-0' },
          { title: '0-0-1-1', key: '0-0-1-1' },
          { title: '0-0-1-2', key: '0-0-1-2' },
        ],
      },
      {
        title: '0-0-2',
        key: '0-0-2',
      },
    ],
  },
  {
    title: '0-1',
    key: '0-1',
    children: [
      { title: '0-1-0-0', key: '0-1-0-0' },
      { title: '0-1-0-1', key: '0-1-0-1' },
      { title: '0-1-0-2', key: '0-1-0-2' },
    ],
  },
  {
    title: '0-2',
    key: '0-2',
  },
];

How would I get an array of all values throughout all nests of this obj by the key of id.

For example

input: ["0-0-0"]

i wanna output like this

output: ["0-0-0", "0-0-0-0", "0-0-0-1", "0-0-0-2"]

enter image description here


Solution

  • You can recursively loop over all the children and get the keys that either match one of the target keys or if any of their ancestors have matched one the target keys.

    const data = [
      {
        title: "0-0",
        key: "0-0",
        children: [
          {
            title: "0-0-0",
            key: "0-0-0",
            children: [
              { title: "0-0-0-0", key: "0-0-0-0" },
              { title: "0-0-0-1", key: "0-0-0-1" },
              { title: "0-0-0-2", key: "0-0-0-2" },
            ],
          },
          {
            title: "0-0-1",
            key: "0-0-1",
            children: [
              { title: "0-0-1-0", key: "0-0-1-0" },
              { title: "0-0-1-1", key: "0-0-1-1" },
              { title: "0-0-1-2", key: "0-0-1-2" },
            ],
          },
          {
            title: "0-0-2",
            key: "0-0-2",
          },
        ],
      },
      {
        title: "0-1",
        key: "0-1",
        children: [
          { title: "0-1-0-0", key: "0-1-0-0" },
          { title: "0-1-0-1", key: "0-1-0-1" },
          { title: "0-1-0-2", key: "0-1-0-2" },
        ],
      },
      {
        title: "0-2",
        key: "0-2",
      },
    ];
    
    function getKeys(data, targetKeys) {
      const targetKeysSet = new Set(targetKeys);
      const outputKeys = [];
      function getKeysHelper(data, hasParentMatched = false) {
        data?.forEach((d) => {
          if (targetKeysSet.has(d.key) || hasParentMatched) {
            outputKeys.push(d.key);
            getKeysHelper(d.children, true);
          } else {
            getKeysHelper(d.children);
          }
        });
      }
      getKeysHelper(data);
      return outputKeys;
    }
    
    getKeys(data, ["0-0-0"]);

    Relevant documentations: