1

I have a list of paths with ids and I need to convert it into complete JSON object.

I'm trying to convert this:

 [
        {
            "id": 1,
            "name": "Electronics",
            "path": "Electronics"
        },
        {
            "id": 2,
            "name": "Laptops & PC",
            "path": "Electronics > Laptops & PC"
        },
        {
            "id": 7,
            "name": "Phones & Accessories",
            "path": "Electronics > Phones & Accessories"
        },
        {
            "id": 8,
            "name": "Smartphones",
            "path": "Electronics > Phones & Accessories > Smartphones"
        },
        {
            "id": 9,
            "name": "Android",
            "path": "Electronics > Phones & Accessories > Smartphones > Android"
        },
        {
            "id": 10,
            "name": "iOS",
            "path": "Electronics > Phones & Accessories > Smartphones > iOS"
        }
    ]

to something like this:

let output = [
  {'Electronics' : {id: 1, name: "electronics", path: "electronics", children: [
        {'Laptops & PC' : {id: 2, name: "Laptops & PC",path: "Electronics > Laptops & PC", children: []}},
        {'Phone & Accessories': {id: 7, name: "Phones & Accessories", path: "Electronics > Phones & Accessories", children: [
              {'Smartphones': {id: 8, name: "Smartphones", path: "Electronics > Phones & Accessories > Smartphones", children: [
                    {'Android': {id: 9, name: "Android", path: "Electronics > Phones & Accessories > Smartphones > Android", children: []}},
                    {'iOS': {id: 10, name: 'iOS', path: "Electronics > Phones & Accessories > Smartphones > iOS", children: []}}
                  ]
                }}
            ]}}
      ]}}
];

I got a solution similar to this on Stackoverflow (How to convert an array of paths into JSON structure?) But I couldn't add extra properties to the object using those answers.

Can somebody please help me?

1
  • Is there any reason why you don't want to keep the flat list? You could simply operate on the paths directly: every descendant element of a given path has a common prefix path (e.g. all descendants of 'Electronics' have the common path prefix 'Electronics >'). Commented Aug 25, 2018 at 10:41

3 Answers 3

3

I think the targeted structure of [{key: data},{key: data},..] is a bit overkill, i would just go for [data,data,..] - which can easily be achieved by splitting the path of each item and moving the result scope iteratively:

var data =  [
        {
            "id": 1,
            "name": "Electronics",
            "path": "Electronics"
        },
        {
            "id": 2,
            "name": "Laptops & PC",
            "path": "Electronics > Laptops & PC"
        },
        {
            "id": 7,
            "name": "Phones & Accessories",
            "path": "Electronics > Phones & Accessories"
        },
        {
            "id": 8,
            "name": "Smartphones",
            "path": "Electronics > Phones & Accessories > Smartphones"
        },
        {
            "id": 9,
            "name": "Android",
            "path": "Electronics > Phones & Accessories > Smartphones > Android"
        },
        {
            "id": 10,
            "name": "iOS",
            "path": "Electronics > Phones & Accessories > Smartphones > iOS"
        },
        {
            "id": 11,
            "name": "Software",
            "path": "Software"
        },
        {
            "id": 12,
            "name": "Office",
            "path": "Software > Office"
        }
    ],
    result = [];

data.forEach(item => {
  var path = item.path.split(" > "),
      scope = result;
  path.forEach(key => {
    var match = scope.find(obj => obj.name === key);
    if(match === undefined) {
      var child = {
        "id": item.id,
        "name": item.name,
        "path": item.path,
        "children": []
      };
      scope.push(child);
      scope = child.children;
    } else {
      scope = match.children;
    }
  });
});

console.log(result);

Sign up to request clarification or add additional context in comments.

3 Comments

If you really need the [{key: data},{key: data},..] let me know, no big deal to change the code to get that output.
Thanks for the answer! I wanted to keep it simple but wasn't sure if `[data, data..] would work. And It surely does!
Accepting since it's simpler to understand.
1

you can do it with recursive function to support unlimited children.

 const input = [
        {
            "id": 1,
            "name": "Electronics",
            "path": "Electronics"
        },
        {
            "id": 2,
            "name": "Laptops & PC",
            "path": "Electronics > Laptops & PC"
        },
        {
            "id": 7,
            "name": "Phones & Accessories",
            "path": "Electronics > Phones & Accessories"
        },
        {
            "id": 8,
            "name": "Smartphones",
            "path": "Electronics > Phones & Accessories > Smartphones"
        },
        {
            "id": 9,
            "name": "Android",
            "path": "Electronics > Phones & Accessories > Smartphones > Android"
        },
        {
            "id": 10,
            "name": "iOS",
            "path": "Electronics > Phones & Accessories > Smartphones > iOS"
        }
    ]
    
    const output = {}
    const pushToOutput = (path,obj,value) =>{
    const clone = {...value}
    const key = path[0];
        if(obj[key] === undefined){
            obj[key] =clone
            obj[key].children = {};
        }
       path.shift()
       if(path.length > 0){
            return pushToOutput(path,obj[key].children,clone)
       }
       obj[key] = clone

    }
    input.forEach(value=>{
       const path =  value.path.split(" > ")
       pushToOutput(path,output,value)
    })
    
    console.log(output)
    

Comments

-1

Use code to convert object to json string.If you are trying create a hierarchical object as below you will need json string which could be parsed through js.

With the object abocve cannot generate the json object as below. It is totally different structure.

    <script>
var a=[
  {'Electronics' : {id: 1, name: "electronics", path: "electronics", children: [
        {'Laptops & PC' : {id: 2, name: "Laptops & PC",path: "Electronics > Laptops & PC", children: []}},
        {'Phone & Accessories': {id: 7, name: "Phones & Accessories", path: "Electronics > Phones & Accessories", children: [
              {'Smartphones': {id: 8, name: "Smartphones", path: "Electronics > Phones & Accessories > Smartphones", children: [
                    {'Android': {id: 9, name: "Android", path: "Electronics > Phones & Accessories > Smartphones > Android", children: []}},
                    {'iOS': {id: 10, name: 'iOS', path: "Electronics > Phones & Accessories > Smartphones > iOS", children: []}}
                  ]
                }}
            ]}}
      ]}}
];
console.log(JS.stringify(a));
</script>

4 Comments

This doesnt answer the question
What you exactly want. You are saying to get second json object from first one !! Is it.
That's not my question. @Dev Aggarwal is asking to convert an array structure into a nested object, not to parse an array into JSON ;)
There should be a parent_id key in the first object in every sub array that it can be hierarchically arranged or it will need to arrange from path key.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.