Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create nested array in Javascript

Tags:

javascript

I'm trying to convert my data from API to my needs. Would like to create a nested array from plain array. I would like to group elements by parentId property, if parentId would not exist I would put it as a root. id value is unique. Like so (raw data):

[
    {id: 1, name: 'sensor'},
    {id: 2, name: 'sensor', parent: 1},
    {id: 3, name: 'sensor', parent: 1},
    {id: 4, name: 'sensor', parent: 3},
    {id: 5, name: 'sensor'},
    {id: 6, name: 'sensor', parent: 5}
]

Converted Data:

  const results = [
    {
      id: 1,
      name: "sensor",
      children: [
        { id: 2, name: "sensor", parent: 1 },
        {
          id: 3,
          name: "sensor",
          parent: 1,
          children: [{ id: 4, name: "sensor", parent: 3 }]
        }
      ]
    },
    { id: 5, name: "sensor", children: [{ id: 6, name: "sensor", parent: 5 }] }
  ];

I found this recursive method but it assumes that the parent property exist for every element in an array. In my example root level element would not have parent property.

function getNestedChildren(arr, parent) {
    var out = []
    for(var i in arr) {
        if(arr[i].parent == parent) {
            var children = getNestedChildren(arr, arr[i].id)

            if(children.length) {
                arr[i].children = children
            }
            out.push(arr[i])
        }
    }
    return out
}
like image 426
Maciej Czarnota Avatar asked May 13 '19 15:05

Maciej Czarnota


People also ask

Can you have nested arrays in JavaScript?

Nested Array in JavaScript is defined as Array (Outer array) within another array (inner array). An Array can have one or more inner Arrays. These nested array (inner arrays) are under the scope of outer array means we can access these inner array elements based on outer array object name.

How do nested arrays work in JavaScript?

After creating a JavaScript nested array, you can use the “push()” and “splice()” method for adding elements, “for loop” and “forEach()” method to iterate over the elements of the inner arrays, “flat()” method for reducing the dimensionality, and “pop()” method to delete sub-arrays or their elements from the nested ...

Can you have an array within an array?

An array is an ordered collection of values: each value is called an element, and each element has a numeric position in the array, known as its index. JavaScript lets us create arrays inside array called Nested Arrays. Nested Arrays have one or many arrays as the element of an array.

How do I create a nested object in JavaScript?

const obj = { code: "AA", sub: { code: "BB", sub: { code: "CC", sub: { code: "DD", sub: { code: "EE", sub: {} } } } } }; Notice that for each unique couple in the string we have a new sub object and the code property at any level represents a specific couple.


4 Answers

You could take an approach which uses both relations, one from children to parent and vice versa. At the end take the children of the root node.

This approach works for unsorted data.

var data = [{ id: 1, name: 'sensor' }, { id: 2, name: 'sensor', parent: 1 }, { id: 3, name: 'sensor', parent: 1 }, { id: 4, name: 'sensor', parent: 3 }, { id: 5, name: 'sensor' }, { id: 6, name: 'sensor', parent: 5 }],
    tree = function (data, root) {
        var t = {};
        data.forEach(o => {
            Object.assign(t[o.id] = t[o.id] || {}, o);
            t[o.parent] = t[o.parent] || {};
            t[o.parent].children = t[o.parent].children || [];
            t[o.parent].children.push(t[o.id]);
        });
        return t[root].children;
    }(data, undefined);
    
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 100
Nina Scholz Avatar answered Oct 03 '22 03:10

Nina Scholz


Given the limited amount of information (will update if more info is added).

The algorithm would be, given an array of data entries, check if entry has a parent and if that parent exists, in which case we want to add the entry to the array of children of the parent entry otherwise add the entry as a parent.

var dataFromAPI = [
    {id: 1, name: 'sensor'},
    {id: 2, name: 'sensor', parent: 1},
    {id: 3, name: 'sensor', parent: 1},
    {id: 4, name: 'sensor', parent: 3},
    {id: 5, name: 'sensor'},
    {id: 6, name: 'sensor', parent: 5}
];


var transformedData = { };

dataFromAPI.forEach(function(entry){

    if(entry.parent !== undefined && entry.parent in transformedData) {
       transformedData[entry.parent].children.push(entry);
    } else {
        entry["children"] = [];
        transformedData[entry.id] = entry;
    }
});

console.log(transformedData);
Please note:

there are a couple assumptions made within this algorithm/code. It assumes that all parent entries exist before their child entry. It also only accounts for two levels (parent or child), meaning a child cannot act as the parent (otherwise you'd have to store the children as an object and not an array)

like image 23
Hermes Avatar answered Oct 03 '22 01:10

Hermes


use a for loop to go through each item. check if parent property exists (or has value). If not its a child item. Attach it to appropriate parent.

to check if property exists:

var myProp = 'prop';
if (myObj.hasOwnProperty(myProp)) {
  alert("yes, i have that property");
}
like image 37
Farhan Avatar answered Oct 03 '22 03:10

Farhan


try

let h={}, r=[]; // result in r
d.forEach(x=> (h[x.id]=x, x.children=[]) );
d.forEach(x=> x.parent ? h[x.parent].children.push(x) : r.push(x) );

let d = [
    {id: 1, name: 'sensor'},
    {id: 2, name: 'sensor', parent: 1},
    {id: 3, name: 'sensor', parent: 1},
    {id: 4, name: 'sensor', parent: 3},
    {id: 5, name: 'sensor'},
    {id: 6, name: 'sensor', parent: 5}
];

let h = {},r = []; // result in r
d.forEach(x => (h[x.id] = x, x.children = []));
d.forEach(x => x.parent ? h[x.parent].children.push(x) : r.push(x));

console.log(r);
like image 25
Kamil Kiełczewski Avatar answered Oct 03 '22 02:10

Kamil Kiełczewski