score:6

Accepted answer

this solution assumes that you use unique id for each item in the tree.

it uses depth first search algorithm.

before trying please fix your sample data non-unique ids. i didn't notice them at first and wasted time debugging for no bug.

function dfs(node, term, foundids) {
  // implement your search functionality
  let ismatching = node.name && node.name.indexof(term) > -1;

  if (array.isarray(node.children)) {
    node.children.foreach((child) => {
      const hasmatchingchild = dfs(child, term, foundids);
      ismatching = ismatching || hasmatchingchild;
    });
  }

  // we will add any item if it matches our search term or if it has a children that matches our term
  if (ismatching && node.id) {
    foundids.push(node.id);
  }

  return ismatching;
}

function filter(data, matchedids) {
  return data
    .filter((item) => matchedids.indexof(item.id) > -1)
    .map((item) => ({
      ...item,
      children: item.children ? filter(item.children, matchedids) : [],
    }));
}

function search(term) {
  // we wrap data in an object to match the node shape
  const datanode = {
    children: data,
  };

  const matchedids = [];
  // find all items ids that matches our search (or their children does)
  dfs(datanode, term, matchedids);

  // filter the original data so that only matching items (and their fathers if they have) are returned
  return filter(data, matchedids);
}

Related Query

More Query from same tag