Carol Pettirossi
Carol Pettirossi

Reputation: 41

Javascript - Recursive object manipulation

I'm having some difficulties with recursive functions. Can someone help me?

I have the following structure:

{
  "entity": {
    "entityLabel": "Virtual Reality",
    "parent": [
      {
        "entity": {
          "entityLabel": "Artificial Intelligence",
          "parent": [
            {
              "entity": {
                "entityLabel": "Information Technology"
              }
            }
          ]
        }
      }
    ]
  }
}

And I need the following result:

{
  "label": "Information Technology",
  "children": [
    {
      "label": "Artificial Intelligence"
      "children": [ 
        { 
          label: "Virtual Reality" 
        } 
      ]
    }
  ]
}

I couldn't accomplish the reverse order. My current code is:

const termTree = term => {
  const label = term.entity?.entityLabel
  const parentArr = term.entity?.parent
  const obj = {}

  let children = []

  if (parentArr) {
    children = parentArr.map(item => {
      return termTree(item)
    })
  }

  obj.label = label

  if (!empty(children)) obj.children = children

  return obj
}

Which results in the same order but with different labels:

{
  "label": "Virtual Reality",
  "children": [
    {
      "label": "Artificial Intelligence",
      "children": [
        {
          "label": "Information Technology"
        }
      ]
    }
  ]
}

As you can see it's reverse and it's not just a matter of changing labels.

Thanks

Upvotes: 0

Views: 165

Answers (1)

Nina Scholz
Nina Scholz

Reputation: 386634

You could take an iterative and recursive approach by handing over a source array for the new label and a target array for the final result with children.

By taking the above wanted format, without a children property in the most inner object, this approach take as target an object with a children. The reducing part for generating the new data structure takes only objects as return value and creates children if necessary.

var data = { entity: { entityLabel: "Virtual Reality", parent: [{ entity: { entityLabel: "Artificial Intelligence", parent: [{ entity: { entityLabel: "Information Technology" } }] } }] } },
    result = [];

[data].forEach(function iter(source, target) {
    return function ({ entity: { entityLabel, parent } }) {
        source = [entityLabel, ...source];
        if (parent) return parent.forEach(iter(source, target));
        source.reduce((t, label) => {
            var temp = (t.children = t.children || []).find(o => o.label === label);
            if (!temp) {
                t.children.push(temp = { label });
            }
            return temp;
        }, target);
    }
}([], { children: result }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Related Questions