Hi, I have created a function that searches for a category in a category tree object and returns all the paths for it as an array of strings, please advice how I can improve it ?
the result im getting now is :
["vehicles",["cars","mercedes"],["trucks","mercedes"],["motorcycles","BMW"]]
i need it in one dimesional array like this :
["vehicles","cars","mercedes","trucks","mercedes","motorcycles","BMW"]

here is also a plunker url for the same code im trying t solve :
Click Here
thanks in advance,
please advice.

var categories = {category:"vehicles",children:[
                 {category:"cars",children:[{category:"mercedes",children:[]}]},
                 {category:"trucks",children:[{category:"mercedes",children:[]}]},
                 {category:"motorcycles",children:[{category:"BMW",children:[]}]}
]};

function getnodes(nodes)
{
 var arr=[];
  if (!nodes.children.length) return nodes.category;
  else{
    arr.push(nodes.category);
  for(var i =0 ; i<nodes.children.length ; i++){
      arr.push(getnodes(nodes.children[i]));
  }
  }
     return arr;
}

 var allnodes = getnodes(categories);
 console.log(JSON.stringify(allnodes));

Dani AI

Generated

— good progress. The confusing nested-array result comes from mixing return types: when a leaf returns a string but an internal node returns an array, pushing the recursive return produces nested arrays. Two simpler, more robust patterns avoid that class of bug.

A straightforward recursive accumulator (always mutates a single result array) keeps the traversal logic simple and guarantees a one-dimensional array:

function collectCategories(node, out = []) {
  out.push(node.category);
  for (let i = 0; i < node.children.length; i++) {
    collectCategories(node.children[i], out);
  }
  return out;
}

If you prefer non-recursive code (safer for very deep trees), use an explicit stack:

function flattenIterative(root) {
  const stack = [root];
  const res = [];
  while (stack.length) {
    const n = stack.pop();
    res.push(n.category);
    for (let i = n.children.length - 1; i >= 0; i--) stack.push(n.children[i]);
  }
  return res;
}

If the real goal is "paths" (every root→leaf sequence) instead of a single flat list, return an array of paths (each path an array) and then join or flatten only when needed. For unique values prefer Array.from(new Set(result)) rather than indexOf filtering — clearer intent and better performance on larger lists.

Notes: avoid changing the original tree, pick the traversal order you need (pre‑order above), and choose iterative traversal if you expect very deep trees to prevent call‑stack overflow.

i have solved it :

var categories = {category:"vehicles",children:[
                 {category:"cars",children:[{category:"mercedes",children:[]}]},
                 {category:"trucks",children:[{category:"mercedes",children:[]}]},
                 {category:"motorcycles",children:[{category:"BMW",children:[]}]}
]};

function getnodes(nodes)
{
 var arr=[];
  if (!nodes.children.length) return nodes.category;
  else{
    arr=arr.concat(nodes.category);
  for(var i =0 ; i<nodes.children.length ; i++){
      arr=arr.concat(getnodes(nodes.children[i]));
  }
  }
  arr = arr.filter (function (value, index, array) { 
    return array.indexOf (value) == index;
});
     return arr;
}

 var allnodes = getnodes(categories);
 console.log(JSON.stringify(allnodes));
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.