0

I have an array like this:

['IT/Programming/Frontend/Angular1','IT/Programming/Frontend/Angular2','IT/Programming/Frontend/React Js','IT/Programming/Backedn/C#', 'IT/Programming/Backedn/Java','IT/Programming/Backedn/Python','IT/Networking/Internet']

I want to create a nested object like this, It basically a nested object(hierarchy tree structure):

{
      text: 'IT', children: [
        {
          text: 'Programming', children: [{
            text: 'Frontend', children: [
              { text: 'Angular 1'},
              { text: 'Angular 2'},
              { text: 'ReactJS'}
            ]
          }, {
            text: 'Backend', children: [
              { text: 'C#'},
              { text: 'Java'},
              { text: 'Python'}
            ]
          }]
        },
        {
          text: 'Networking',children: [
            { text: 'Internet'},
          ]
        }
      ]
    }

I am able to create nested object but not sure how to add key value, here is my code:

function  createObject(array) {
    let obj = {};
    for (let key of array) {
        let putInto = obj;
        let tokens = key.split('/');
        for (let i = 0; i < tokens.length; i++) {
            let name = tokens[i];
            let value = (i === tokens.length - 1) ? '' : {};
            putInto[name] = putInto[name] || value;
            putInto = putInto[name];
        }
    }
    return obj;
}
createObject(myArr)
john.mark
  • 13
  • 1
  • what is your input array? – ikhvjs May 20 '21 at 09:58
  • `['IT/Programming/Frontend/Angular1','IT/Programming/Frontend/Angular2','IT/Programming/Frontend/React Js','IT/Programming/Backedn/C#', 'IT/Programming/Backedn/Java','IT/Programming/Backedn/Python','IT/Networking/Internet']` – john.mark May 20 '21 at 10:00
  • Would there be an item is not IT/xxx/xx.. such as Account/xxxxxx? – ikhvjs May 20 '21 at 10:05
  • Yes, it could be possible, there can be multiple same level hierarchy, like IT/xx/xx, account/xx/xx/xx, support/xx/xx – john.mark May 20 '21 at 10:10
  • Also, what if there are duplicate records? such as 2 items are the same. do you ignore the duplicate one or still add it to the object? – ikhvjs May 20 '21 at 10:28

1 Answers1

2

In two steps: first, group strings by the first element in a Map, second, iterate the map and apply the builder recursively:

function makeTreeA(items) {
    let m = new Map

    items.forEach(([text, ...rest]) => {
        if (!m.has(text))
            m.set(text, [])
        if (rest.length)
            m.get(text).push(rest)
    });

    return [...m].map(([text, children]) => children.length
        ? {text, children: makeTreeA(children)}
        : {text}
    )

}

const makeTree = strings => makeTreeA(strings.map(s => s.split('/')))

//

s = ['IT/Programming/Frontend/Angular1', 'IT/Programming/Frontend/Angular2', 'IT/Programming/Frontend/React Js', 'IT/Programming/Backedn/C#', 'IT/Programming/Backedn/Java', 'IT/Programming/Backedn/Python', 'IT/Networking/Internet']
console.log(makeTree(s))
georg
  • 211,518
  • 52
  • 313
  • 390