1

Example JSON:

{
  name: "A",
  childNodes: [{
    name: "B",
    childProps: [{
      prop_list: [{
        name: "BS1"
      }, {
        name: "BS2"
      }]
    }],
    childNodes: [{
      name: "C",
      childProps: [{
        prop_list: [{
          name: "CS1"
        }, {
          name: "CS2"
        }]
      }],

    }]


  }],
  childProps: [{
    prop_list: [{
      name: "AS1"
    }, {
      name: "AS2"
    }]
  }]
}

I want to print output in the following manner.

    A, B, BS1
    A, B, BS2
    A, B, C, CS1
    A, B, C, CS2
    A, AS1
    A, AS2

Basically, I want to print the path to each leaf node. (And I need to get the name property value for each object)

Lizzzz90
  • 125
  • 1
  • 1
  • 8
  • Possible duplicate of [JavaScript flattening an array of arrays of objects](https://stackoverflow.com/questions/29158723/javascript-flattening-an-array-of-arrays-of-objects) – Martin Zeitler Dec 04 '18 at 00:42
  • It's not clear what you don't include the `childProps` of `A` (`CS1` and `AS2`). – Mark Dec 04 '18 at 00:43
  • also see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join – Martin Zeitler Dec 04 '18 at 00:44
  • I have corrected it. AS1 and AS2 are in childProps property of A – Lizzzz90 Dec 04 '18 at 00:44
  • @Lizzzz90 you first have to flatten it to an array; and then `.join(', ')` to string... traversing the structure, while building up the string would work, too. – Martin Zeitler Dec 04 '18 at 00:46
  • @MartinZeitler flattening it or traversing it gives me o/p in this way, { name: 'A', 'childNodes.0.name': 'B', 'childNodes.0.childProps.0.prop_list.0.name': 'BS1', 'childNodes.0.childProps.0.prop_list.1.name': 'BS2', 'childNodes.0.childNodes.0.name': 'C', 'childNodes.0.childNodes.0.childProps.0.prop_list.0.name': 'CS1', 'childNodes.0.childNodes.0.childProps.0.prop_list.1.name': 'CS2', 'childProps.0.prop_list.0.name': 'AS1', 'childProps.0.prop_list.1.name': 'AS2' } Can you please be more specific as to how I can collect just the values of "name" from each path? – Lizzzz90 Dec 04 '18 at 00:54
  • That's not JSON. – melpomene Dec 04 '18 at 01:22

2 Answers2

0

To solve your problem you must loop over each item in your object and use a recursive function to append nested names to your path string.

Here is an example to get you started

var obj = {
  name: "A",
  childNodes: [{
    name: "B",
    childProps: [{
      prop_list: [{
        name: "BS1"
      }, {
        name: "BS2"
      }]
    }],
    childNodes: [{
      name: "C",
      childProps: [{
        prop_list: [{
          name: "CS1"
        }, {
          name: "CS2"
        }]
      }],

    }]


  }],
  childProps: [{
    prop_list: [{
      name: "AS1"
    }, {
      name: "AS2"
    }]
  }]
};

(function findName(o, path = '') {
  const isLastLevel = !o.childProps && !o.childNodes;
  path += isLastLevel ? o.name : o.name + ', ';

  if (o.childProps) {
    o.childProps.forEach(props => {
      props.prop_list.forEach(prop => {
        findName(prop, path);
      });
    });
  }

  if (o.childNodes) {
    o.childNodes.forEach(node => {
      findName(node, path);
    });
  }

  if (isLastLevel) {
    console.log(path);
  }
})(obj);
itodd
  • 2,278
  • 1
  • 14
  • 14
0

Perhaps you could take a more generalized approach to implementing this using recusion, so that your traversal works for any format of input data:

function printPaths(node, path) {

  const nodeName = node.name ? (path ? ',' : '') + node.name : ''
  const nodePath = (path ? path : '') + nodeName  
  const nodeChildren = Object.values(node).filter(Array.isArray).flat()

  return nodeChildren.length > 0 ? nodeChildren
  .map(nodeChild => printPaths(nodeChild, nodePath)).flat() : nodePath
}

This solution is decoupled from your specific format of input data, meaning it will examine the current node object and traverse any array values found, eventually returning all discovered the paths:

var input = {
  name: "A",
  childNodes: [{
    name: "B",
    childProps: [{
      prop_list: [{
        name: "BS1"
      }, {
        name: "BS2"
      }]
    }],
    childNodes: [{
      name: "C",
      childProps: [{
        prop_list: [{
          name: "CS1"
        }, {
          name: "CS2"
        }]
      }],
    }]
  }],
  childProps: [{
    prop_list: [{
      name: "AS1"
    }, {
      name: "AS2"
    }]
  }]
}

function printPaths(node, path) {
  
  const nodeName = node.name ? (path ? ',' : '') + node.name : ''
  const nodePath = (path ? path : '') + nodeName  
  const nodeChildren = Object.values(node).filter(Array.isArray).flat()
    
  return nodeChildren.length > 0 ? nodeChildren
  .map(nodeChild => printPaths(nodeChild, nodePath)).flat() : nodePath
}

console.log( printPaths(input) )
Dacre Denny
  • 29,664
  • 5
  • 45
  • 65