Home > Mobile >  Search item in multidimensional array
Search item in multidimensional array

Time:03-15

I'm working with a tree nodes and I want to create a function to find an item by its ID.

What is the best and optimal solution to get it?

I think it will be a recursive function, but I'm not sure and I want a help please to choose what I will use to resolve this issue :)

This is my example:

const treeData = [
  {
    title: 'parent 1',
    key: 11,
    children: [
      {
        title: 'parent 1-0',
        key: 12,
       
        children: [
          {
            title: 'leaf',
            key: 13,
            
            children: [
              {
                title: 'leaf111',
                key: 14,
               
              },
              {
                title: 'leaf',
                key: 15,
              },
            ],
          },
          {
            title: 'leaf666',
            key:88,
          },
        ],
      },
      {
        title: 'parent 1-1',
        key: 55,
        children: [
          {
            title: (
              <span
                style={{
                  color: '#1890ff',
                }}
              >
                sss
              </span>
            ),
            key: '0-0-1-0',
          },
        ],
      },
    ],
  },
];

Input : 14

Output : {title: 'leaf111',key: 14},

CodePudding user response:

We can create a rerusive function that:

  • Loops though each object in the array and
    • Returns the object if id matches
    • Calls itself with the objects children

const treeData = [{title: 'parent 1', key: 11, children: [{title: 'parent 1-0', key: 12, children: [{title: 'leaf', key: 13, children: [{title: 'leaf111', key: 14, }, {title: 'leaf', key: 15, }, ], }, {title: 'leaf666', key:88, }, ], }, {title: 'parent 1-1', key: 55, children: [{title: '(<span style={{color: \'#1890ff\', }} > sss </span> )', key: '0-0-1-0', }, ], }, ], }, ];

const findById = (e, id) => {
    for (let o of e) {
        return (o.key == id) ? o : findById(o.children, id);
    }
}

const res = findById(treeData, 14);
console.log(res);

Output:

{
  "title": "leaf111",
  "key": 14
}

CodePudding user response:

You can use a tree walker, which traverses the tree and calls a provided function upon visiting each node. The provided function could check to see if the node matches the provided ID.

An example:

function getNodeById(id) {
  let matchingNode;
  walk(tree, node => {
    if(node.key === 14) {
       matchingNode = node;
    }
  });
  return matchingNode;
}

A tree walker can be implemented using recursion, as you mention. In a preorder operation, which starts at the topmost node, the walker takes the tree (the root node) and on each invocation:

  • calls the callback function with the current node
  • for each child node, calls itself with the child node and callback
function walker(node, cb) {
  cb(node);
  if (Array.isArray(node.children)) {
    node.children.forEach(child => walker(child, cb));
  }
}

For use with React, you can implement your own walking using React.Children.forEach, or you may prefer try a library like https://github.com/FormidableLabs/react-ssr-prepass.

  • Related