how to create from object and nested objects one array - javascript

I have this array of objects with nested objects "children".. the number of nested children arrays that can be is not defined
let a = [
{ id: 0, title: 'a', children: [ { id: 1, title: 'aa', children: [ { id: 2, title: 'aaa', children: []} ]}] },
{ id: 3, title: 'b', children: [ { id: 4, title: 'bb', children: []}] },
{ id: 5, title: 'c', children: [] },
{ id: 6, title: 'd', children: [ { id: 7, title: 'dd', children: [ { id: 8, title: 'ddd', children: []} ]}] },
]
and I need foreach them, take to the array.. with level of nested:
let b = [
{ id: 0, title: 'a', level: 0 },
{ id: 1, title: 'aa', level: 1 },
{ id: 2, title: 'aaa', level: 2 },
{ id: 3, title: 'b', level: 0 },
{ id: 4, title: 'bb', level: 1 },
{ id: 5, title: 'c', level: 0 },
{ id: 6, title: 'd', level: 0 },
{ id: 7, title: 'dd', level: 1 },
{ id: 8, title: 'ddd', level: 2 },
]
I tired recursively code, but its not working.. thank for help

Here is a recursive function called makeLevels that outputs your result.
let a = [
{ id: 0, title: 'a', children: [{ id: 1, title: 'aa', children: [{ id: 2, title: 'aaa', children: [] }] }] },
{ id: 3, title: 'b', children: [{ id: 4, title: 'bb', children: [] }] },
{ id: 5, title: 'c', children: [] },
{ id: 6, title: 'd', children: [{ id: 7, title: 'dd', children: [{ id: 8, title: 'ddd', children: [] }] }] },
];
function makeLevels(entry, result = [], level = 0) {
for (let i = 0, len = entry.length; i < len; i++) {
const item = entry[i];
result.push({ id: item.id, title: item.title, level });
if (item.children?.length) {
makeLevels(item.children, result, level + 1);
}
}
return result;
}
console.log(makeLevels(a));
Output:
[
{ "id": 0, "title": "a", "level": 0 },
{ "id": 1, "title": "aa", "level": 1 },
{ "id": 2, "title": "aaa", "level": 2 },
{ "id": 3, "title": "b", "level": 0 },
{ "id": 4, "title": "bb", "level": 1 },
{ "id": 5, "title": "c", "level": 0 },
{ "id": 6, "title": "d", "level": 0 },
{ "id": 7, "title": "dd", "level": 1 },
{ "id": 8, "title": "ddd", "level": 2 }
]

You can try this approach:
let a = [{ id: 0, title: 'a', children: [ { id: 1, title: 'aa', children: [ { id: 2, title: 'aaa', children: []} ]}] }, { id: 3, title: 'b', children: [ { id: 4, title: 'bb', children: []}] }, { id: 5, title: 'c', children: [] }, { id: 6, title: 'd', children: [ { id: 7, title: 'dd', children: [ { id: 8, title: 'ddd', children: []} ]}] },]
function flattenArray(arr, index = 0) {
return arr.reduce((acc, {children, ...rest}) => [
...acc,
{...rest, level: index},
...flattenArray(children, index+1)
],
[])
}
console.log(flattenArray(a))

To make it a little more readable, you could also do it like this.
let a = [{ id: 0, title: 'a', children: [ { id: 1, title: 'aa', children: [ { id: 2, title: 'aaa', children: []} ]}] }, { id: 3, title: 'b', children: [ { id: 4, title: 'bb', children: []}] }, { id: 5, title: 'c', children: [] }, { id: 6, title: 'd', children: [ { id: 7, title: 'dd', children: [ { id: 8, title: 'ddd', children: []} ]}] },]
function levels(obj, level = 0, arr = []) {
for (const { id, title, children } of obj) {
arr.push({ id, title, level });
if (Array.isArray(children)) levels(children, level + 1, arr);
}
return arr;
}
console.log(levels(a))

Related

How to collect all the objects in the object into a single array

When I click the button, I want to include all the objects in the itemSold and itemGet objects of the customers into the products array. how can I do that?
let customers = [{
active: true,
id: 1,
product: {
itemSold: [{id:1,name : 'car'}, {id:2,name : 'home'}],
itemGet: [{id:3,name : 'phone'}, {id:4,name : 'fly'}],
},
},
{
active: true,
id: 2,
product: {
itemSold: [{id:5,name : 'lamb'}, {id:6,name : 'mouse'}],
itemGet: [{id:7,name : 'mouse pad'}, {id:8,name : 'tv'}],
},
},
];
let clickButton = document.querySelector("#clickButton");
let products = [];
clickButton.addEventListener("click", getProcuts()});
function getProducts(){}
<button id="clickButton" >Click
</button>
let customers = [{
active: true,
id: 1,
product: {
itemSold: [{ id: 1, name: 'car' }, { id: 2, name: 'home' }],
itemGet: [{ id: 3, name: 'phone' }, { id: 4, name: 'fly' }],
},
},
{
active: true,
id: 2,
product: {
itemSold: [{ id: 5, name: 'lamb' }, { id: 6, name: 'mouse' }],
itemGet: [{ id: 7, name: 'mouse pad' }, { id: 8, name: 'tv' }],
},
},
];
let clickButton = document.querySelector("#clickButton");
let products = [];
clickButton.addEventListener("click", getProducts);
function getProducts() {
for (let i = 0; i < customers.length; i++) {
products.push(...customers[i].product.itemGet, ...customers[i].product.itemSold);
}
console.log(products);
}
<button id="clickButton">Click</button>
We loop our customers array and then select product property there we push both itemSold and itemGet arrays into products.
You can map over the customers and concatenate the arrays.
const customers = [
{
active: true,
id: 1,
product: {
itemSold: [
{ id: 1, name: "car" },
{ id: 2, name: "home" },
],
itemGet: [
{ id: 3, name: "phone" },
{ id: 4, name: "fly" },
],
},
},
{
active: true,
id: 2,
product: {
itemSold: [
{ id: 5, name: "lamb" },
{ id: 6, name: "mouse" },
],
itemGet: [
{ id: 7, name: "mouse pad" },
{ id: 8, name: "tv" },
],
},
},
];
const products = customers.map((customer) => {
return customer.product.itemSold.concat(customer.product.itemGet);
});
console.log(products);
const customers = [
{
active: true,
id: 1,
product: {
itemSold: [
{ id: 1, name: "car" },
{ id: 2, name: "home" },
],
itemGet: [
{ id: 3, name: "phone" },
{ id: 4, name: "fly" },
],
},
},
{
active: true,
id: 2,
product: {
itemSold: [
{ id: 5, name: "lamb" },
{ id: 6, name: "mouse" },
],
itemGet: [
{ id: 7, name: "mouse pad" },
{ id: 8, name: "tv" },
],
},
},
];
const products = customers.map((customer) => {
return customer.product.itemSold.concat(customer.product.itemGet).flat();
});
console.log(products.flat());

i wanna get the max depth of a not-certain tree. the tree looks like below,how can i finish it

given a tree-structured data, get the max height of the tree. i wanna get the max depth of a not-certain tree. the tree looks like below:
{
id: 1,
label: 'label1',
children: [{
id: 3,
label: 'label2',
children: [{
id: 4,
label: 'label3'
}, {
id: 5,
label: 'label4',
disabled: true,
children: [{
id: 4,
label: 'label3'
}, {
id: 5,
label: 'label4',
disabled: true
}]
}]
}
i tried as below, but it did not work as expected.
const maxDepth = o => {
if(!o || !o.children) return 0;
let arr = []
for(let i = 0; i< o.children.length; i++) {
arr[i] = maxDepth(o.children[i])
}
let max = Math.max(...[arr]) + 1
return max
}
I don't believe your data is formatted 100% correctly, so I took the liberty of doing so. That being said, this screams for a recursive algorithm.
{
id: 1,
label: 'label1',
children: [{
id: 3,
label: 'label2',
children: [{
id: 4,
label: 'label3'
},
{
id: 5,
label: 'label4',
disabled: true,
children: [{
id: 4,
label: 'label3'
},
{
id: 5,
label: 'label4',
disabled: true
}]
}]
}]
}
test1 = {
id: 1,
label: "test1",
children: []
}
test2 = {
id: 2,
label: "test1",
children: [
{
id: 2,
label: "test2",
children: []
},
{
id: 2,
label: "test2",
children: []
}]
}
test3 = {
id: 3,
label: "test1",
children: [
{
id: 3,
label: "test2",
children: [{
children: [{
children: [{}]
}]
}]
},
{
id: 3,
label: "test2",
children: [{}]
}]
}
your_data = {
id: 1,
label: 'label1',
children: [{
id: 3,
label: 'label2',
children: [{
id: 4,
label: 'label3'
},
{
id: 5,
label: 'label4',
disabled: true,
children: [{
id: 4,
label: 'label3'
},
{
id: 5,
label: 'label4',
disabled: true
}]
}]
}]
}
my_data = {
id: 1,
label: 'label1',
children: [{
id: 3,
label: 'label2',
children: [{
id: 4,
label: 'label3'
},
{
id: 5,
label: 'label4',
disabled: true,
children: [{
id: 4,
label: 'label3'
},
{
id: 5,
label: 'label4',
disabled: true
}]
}]
},
{
id: 6,
label: 'madeup1',
children: [{
id: 7,
label: 'madeup2',
children: [{
id: 8,
label: 'madeup3',
children: [{
id: 9,
label: 'madeup4'
}]
}]
}]
}]
}
function max_depth(exploringTheDepthsOf)
{
largest = 0;
if (exploringTheDepthsOf.hasOwnProperty('children'))
{
for (var i = 0; i < exploringTheDepthsOf["children"].length; i++)
{
largest = Math.max(largest, max_depth(exploringTheDepthsOf["children"][i]));
}
}
else
{
return 0;
}
return largest + 1;
}
console.log("returned value", max_depth(test1));
console.log("returned value", max_depth(test2));
console.log("returned value", max_depth(test3));
console.log("returned value", max_depth(your_data));
console.log("returned value", max_depth(my_data));
This is about as close as I could get. Geeks for geeks has a pretty good artical on it and javascript code to show you how to do it, but its for actual nodes, not for json like objects: https://www.geeksforgeeks.org/depth-n-ary-tree/

Assign new properties to an array of Objects

I have an array of Objects
const options = [
{ id: 1, name: "Back Pain" },
{ id: 2, name: "Body aches" },
{ id: 3, name: "Cold Sores" },
{ id: 4, name: "Cough" },
{ id: 5, name: "Constipation" },
];
I am trying to write a function that will assign new properties to the object.
The output I am looking for is:
const options = [
{ value: 1, label: "Back Pain" },
{ value: 2, label: "Body aches" },
{ value: 3, label: "Cold Sores" },
{ value: 4, label: "Cough" },
{ value: 5, label: "Constipation" },
];
I have tried to loop through the array using a for loop, but can not figure it out.
Thanks for the help:)
You can do it like this:
const data=[{ id: 1, name: "Back Pain" },
{ id: 2, name: "Body aches" },
{ id: 3, name: "Cold Sores" },
{ id: 4, name: "Cough" },
{ id: 5, name: "Constipation" },
];
var result = data.map(({id:value, name:label})=>({value, label}));
console.log(result);

Treeview in javascript

I need to make something similar to treeview. It doesn't need collapsing it just needs to show some heirachy, but in a table view.
Flat data comes in from a database. I unflattened it and made a tree, but now that it's a tree, I wanted to turn it back into an array, so I can easily iterate using a for loop.
After looking at the source code of other treeviews my method was going to be like this:
From flat data from a db, unflatten:
[
{ id: 1, name: 'node1', parentId: 0 },
{ id: 2, name: 'node2', parentId: 1 },
{ id: 4, name: 'node4', parentId: 2 },
{ id: 5, name: 'node5', parentId: 2 },
{ id: 6, name: 'node6', parentId: 3 },
{ id: 3, name: 'node3', parentId: 1 },
]
The tree is now ordered and has a hierarchy (levels for indentation). Traverse the tree. I add level and children.
[
id: 1,
name: 'node1',
level: 0,
children: [
{
id: 2,
name: 'node2',
parentId: 1,
level: 1
children: [
{
id: 4,
name: 'node4',
parentId: 2,
level: 2,
children: []
},
{
id: 5,
name: 'node5',
parentId: 2,
children: []
},
]
},
{
id: 3,
name: 'node1',
parentId: 1,
children: [
{
id: 6,
name: 'node6',
parentId: 3,
children: []
},
]
},
]
]
Compress it back into an array form with order, level.
[
{ id: 1, name: 'node1', level: 0, parentId: 0, children: [...] },
{ id: 2, name: 'node2', level: 1, parentId: 1, children: [...] },
{ id: 4, name: 'node4', level: 2, parentId: 2, children: [...] },
{ id: 5, name: 'node5', level: 2, parentId: 2, children: [...] },
{ id: 3, name: 'node3', level: 1, parentId: 1, children: [...] },
{ id: 6, name: 'node6', level: 2, parentId: 3, children: [...] },
]
Of which I can easily create a table from.
I've gotten close with the following code:
var data = [
{ id: 1, name: 'node1', parentId: 0 },
{ id: 2, name: 'node2', parentId: 1 },
{ id: 4, name: 'node4', parentId: 2 },
{ id: 5, name: 'node5', parentId: 2 },
{ id: 6, name: 'node6', parentId: 3 },
{ id: 3, name: 'node3', parentId: 1 }
]
function unflatten (arr, parentId, level) {
let output = []
for (const obj of arr) {
if (obj.parentId === parentId) {
var children = unflatten(arr, obj.id, level+1)
obj.level = level
if (children.length) {
obj.children = children
}
output.push(obj)
}
}
// console.log(output)
return output
}
function flatten (tree) {
var output = []
for(const node of tree) {
if(node.children !== undefined){
var nodeChildren = flatten(node.children.reverse())
for(const child of nodeChildren){
output.push(child)
}
}
output.push(node)
}
return output
}
var dataCopy = Object.assign([], data)
console.log('data', dataCopy)
var res = unflatten(data, 0, 0)
console.log('tree', res)
var resCopy = Object.assign([], res)
var res2 = flatten(resCopy)
console.log('reflatten', res2)
Fiddle http://jsfiddle.net/ctd09r85/10/
That fiddle is the closest I've gotten, but it's a bit reversed and out of order.
How can I do this, and is this a reasonable way to build the tree view.

flatten tree with javascript and es6 features

i am new in es6 and want to flatten my tree object.
(I'm using reflux - not redux - but flatten state is also a good idea in reflux)
api response:
export const node = {
item: 1,
children: [
{
item: 2,
children: [
{
item: 3,
children: [
{
item: 4,
children: []
},
{
item: 5,
children: []
},
{
item: 6,
children: [
{
item: 7,
children: []
},
{
item: 8,
children: []
},
{
item: 9,
children: []
}
]
}
]
},
{
item: 10,
children: [
{
item: 11,
children: []
},
{
item: 12,
children: [
{
item: 13,
children: []
},
{
item: 14,
children: []
}
]
}
]
}
]
}
]
}
My goal is:
tree= {
byId: {
item1 : {
id: 'item1',
name: 'item1', parent: null,
children : ['item2']
}
}
parent is one id, childrend are array of ids
for building a breadcrumb (using parent) or listing child objects...
get object from id with
tree.byId[someId]
my last try ist to use a recursiv function with es6 spread operator:
const flattenTree = (tree, flattenTree) => {
if (node.children.length) {
node.children.map(child => {
return flattenTree(child, [...tree= { id: child.item}])
})
} else {
return [...tree, tree.byId[cat.item] = { id: cat.item, name: cat.item }]
}
}
sorry I'm first time here, so my post in not well formatted...
thx for help
const tree = {
item: 1,
children: [
{
item: 2,
children: [
{
item: 3,
children: [
{
item: 4,
children: []
},
{
item: 5,
children: []
},
{
item: 6,
children: [
{
item: 7,
children: []
},
{
item: 8,
children: []
},
{
item: 9,
children: []
}
]
}
]
},
{
item: 10,
children: [
{
item: 11,
children: []
},
{
item: 12,
children: [
{
item: 13,
children: []
},
{
item: 14,
children: []
}
]
}
]
}
]
}
]
}
const flattenTree = (tree) => {
const newTree = { byId: {} };
const traverseNode = (node, parent) => {
const id = `item${node.item}`;
newTree.byId[id] = {
id,
name: id,
parent,
children: node.children.map((c) => {
traverseNode(c, id)
return `item${c.item.id}`;
})
}
}
traverseNode(tree, null);
return newTree;
}
The result of flattenTree(tree) will look something like this:
{ byId:
{ item4:
{ id: 'item4', name: 'item4', parent: 'item3', children: [] },
item5:
{ id: 'item5', name: 'item5', parent: 'item3', children: [] },
item7:
{ id: 'item7', name: 'item7', parent: 'item6', children: [] },
item8:
{ id: 'item8', name: 'item8', parent: 'item6', children: [] },
item9:
{ id: 'item9', name: 'item9', parent: 'item6', children: [] },
item6:
{ id: 'item6', name: 'item6', parent: 'item3', children: [Array] },
item3:
{ id: 'item3', name: 'item3', parent: 'item2', children: [Array] },
item11:
{ id: 'item11', name: 'item11', parent: 'item10', children: [] },
item13:
{ id: 'item13', name: 'item13', parent: 'item12', children: [] },
item14:
{ id: 'item14', name: 'item14', parent: 'item12', children: [] },
item12:
{ id: 'item12',
name: 'item12',
parent: 'item10',
children: [Array] },
item10:
{ id: 'item10',
name: 'item10',
parent: 'item2',
children: [Array] },
item2:
{ id: 'item2', name: 'item2', parent: 'item1', children: [Array] },
item1:
{ id: 'item1', name: 'item1', parent: null, children: [Array] } } }
You can use this recursive function:
Main() {
let flattedTree = [];
// We must treat the tree like a node, so we put it inside an array.
let tree = [
{
item: 1,
children: [
{
item: 2,
children: [
{
item: 3,
children: [
{
item: 4,
children: [],
},
{
item: 5,
children: [],
},
{
item: 6,
children: [
{
item: 7,
children: [],
},
{
item: 8,
children: [],
},
{
item: 9,
children: [],
},
],
},
],
},
{
item: 10,
children: [
{
item: 11,
children: [],
},
{
item: 12,
children: [
{
item: 13,
children: [],
},
{
item: 14,
children: [],
},
],
},
],
},
],
},
],
},
];
// After recursive method executed you will have a flattend array.
// flattedTree variable hold the flatted tree.
this.flatten(tree, flattedTree);
}
flatten(nodes: any[], flattedNodes: any[]) {
for (let index = 0; index < nodes.length; index++) {
flattedNodes.push(nodes[index]);
if (nodes[index].children !== undefined)
if (nodes[index].children.length > 0)
this.flatten(nodes[index].children, flattedNodes);
}
}
This is the result:
[{"item":1,"children":[{"item":2,"children":[{"item":3,"children":[{"item":4,"children":[]},{"item":5,"children":[]},{"item":6,"children":[{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]}]}]},{"item":10,"children":[{"item":11,"children":[]},{"item":12,"children":[{"item":13,"children":[]},{"item":14,"children":[]}]}]}]}]},{"item":2,"children":[{"item":3,"children":[{"item":4,"children":[]},{"item":5,"children":[]},{"item":6,"children":[{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]}]}]},{"item":10,"children":[{"item":11,"children":[]},{"item":12,"children":[{"item":13,"children":[]},{"item":14,"children":[]}]}]}]},{"item":3,"children":[{"item":4,"children":[]},{"item":5,"children":[]},{"item":6,"children":[{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]}]}]},{"item":4,"children":[]},{"item":5,"children":[]},{"item":6,"children":[{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]}]},{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]},{"item":10,"children":[{"item":11,"children":[]},{"item":12,"children":[{"item":13,"children":[]},{"item":14,"children":[]}]}]},{"item":11,"children":[]},{"item":12,"children":[{"item":13,"children":[]},{"item":14,"children":[]}]},{"item":13,"children":[]},{"item":14,"children":[]}]

Categories