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
}
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.
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 ...
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.
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.
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; }
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);
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
)
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");
}
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With