Iterate through nested object javascript - javascript

I have a javascript object with nested objects like this:
Object {
Id: 1,
Descendants: [{
Object {
id:2
Descendants:[
{Object
{id:3
Descendants[]
}}]}]
Now I want to iterate through all of the descendant properties and print them.
What would be the cleanest way to do this?
Thanks a lot in advance!

You could try this:
const o = {
id: 1,
Descendants: [
{
id: 2,
Descendants: [
{
id: 3,
Descendants: [],
},
],
},
],
}
function doSomething(o) {
// Write Do whatever you want to do with the objects
console.log(o.id)
// And to the recursively
for (const child of o.Descendants) {
doSomething(child)
}
}
doSomething(o)

Related

How to add parent key value to all child items in js array?

I have a json where one parent array, and every object of parent array there is another child array pozzles.
So what I want to do is, there is one key-value(title) of parent item I want to add in every item of child array.
Check this json screen shot to understand clear.
Is there any direct method available in js to do this ?
Considering this is your data
const data = [{ id: 1, title: "some", pozzles: [{ id: "1A" }, { id: "1B" }] }, { id: 2, title: "some2", pozzles: [{ id: "2A" }, { id: "2B" }] }];
data.forEach(d => {
d.pozzles.forEach(p => { p.title = d.title })
});

Iterate through an array of nested objects to collect objects that lack a property

I need to iterate through the array of objects as long as the children key has values in it.
Each object in the array will have an individual children array and I need to check if the timeGroupName exists in each of the objects.
And finally, if the timeGroupName is missing in any of the objects, return something to indicate that timeGroupName does not exist. I want to use recursion here.
Sample Object:
[
{
name: "test",
timeGroupName: "NupurGroup",
type: "node",
id: 1592208617196,
children: [
{
name: "sid",
timeGroupName: "NupurGroup",
type: "node",
id: 1592210050837,
children: [
{
name: "rush",
timeGroupName: "NupurGroup",
type: "node",
id: 1592210076303,
children: []
},
{
name: "1",
timeGroupName: "NupurGroup",
type: "store",
storeId: "5c46e5fde6d3c2293e1f53b6",
id: 1592210057381,
children: []
}
],
collapsedStore: false,
collapsedGroup: false
}
],
collapsedGroup: false
}
];
You could use this recursive function:
const findMissing = data => (data || []).flatMap(item =>
("timeGroupName" in item ? [] : [item.id]).concat(findMissing(item.children))
);
This will return an array with the id values of all the objects that have no "timeGroupName" property. In your example all objects have it, so the above function would return [] for it.

Find and update value in array of nested objects

I have an object array as follows:
products = [
{
id: 1,
title: "Product 1",
specifications: {
price: 1.55,
discount: 15,
attributes: [
{
l1: 100,
l2: 80
height:200,
weight: 15,
parameters: [
{
id: 199199 // this is how I identify the parameter
size: 185 // this is what I want to change
}, ...
]
}, ...
]
}
}, ...
]
... and an array of changes to parameters I want to apply, for example: change size to 189 where product.specifications.attributes.parameters.id == 199199.
I'd like to do this without flattening any elements as they are part of a Vue.js data structure, it will break the reactivity.
How could I do this? I am open to using Underscore or lo-dash
This looks ugly, but it is effective:
To make it more dynamic, let's use variables: identifier will be your '199199' value and new_size for the '189' value.
methods: {
updateRecord: function(identifier, new_size) {
this.products.map(function(product) {
product.specifications.attributes.map(function(attribute) {
attribute.parameters.map(function(parameter) {
if (parameter.id == identifier) parameter.size = new_size;
})
});
});
}
}
Here is a working fiddle: https://jsfiddle.net/crabbly/eL7et9e8/
_.forEach(products, function(product) {
_.forEach(_.get(product, 'specifications.attributes', []), function(attribute) {
_.set(_.find(attribute.parameters, {id: 199199}), 'size', 189);
});
});
I believe what you want is underscore's findIndex() - http://underscorejs.org/#findIndex. Once you find which element in the array you want to apply the changes to (comparing the nested id to what you are looking for) you can then make the change to that particular element.

How to include elements of an array in another array?

So for example I have a MAIN array with all the information I need:
$scope.songs = [
{ title: 'Reggae', url:"#/app/mworkouts", id: 1 },
{ title: 'Chill', url:"#/app/browse", id: 2 },
{ title: 'Dubstep', url:"#/app/search", id: 3 },
{ title: 'Indie', url:"#/app/search", id: 4 },
{ title: 'Rap', url:"#/app/mworkouts", id: 5 },
{ title: 'Cowbell', url:"#/app/mworkouts", id: 6 }
];
I want to put only certain objects into another array without typing in each of the objects so the end result will look like
$scope.array1 = [
{ title: 'Reggae', url:"#/app/mworkouts",id: 1 },
{ title: 'Cowbell', url:"#/app/mworkouts",id: 6 }
];
I have tried this with no luck:
$scope.array1 = [
{ $scope.songs[1] },
{ $scope.songs[6] }
];
I will have to do a bunch of these so typing in each object would take forever, is there any faster way to do this? Thanks in advance :)
You need to do something like this:
$scope.array1 = $scope.songs.filter(function (song) {
return (song.title == "Reggae" || song.title == "Cowbell");
});
Here, the filter function will give you a filtered new array to be replaced for the original scope value.
Or in simple way, using the array indices, you can use:
$scope.array1 = [ $scope.songs[0] , $scope.songs[5] ];
You need to remove the braces since it's already an object. Although the array index starts from 0 so change index value based on 0.
$scope.array1 = [
$scope.songs[0] ,
$scope.songs[5]
];

Iterating a javascript collection and adding a sort order

I have a tree in javascript which has multiple root elements and nested children.
Here's the object:
[{
_id: '546d30905d7edd1d5169181d',
name: 'first'
children: []
}, {
_id: '546d30905d7edd1d2169181d',
name: 'second'
children: []
}, {
_id: '446d30905d7edd1d5169181d',
name: 'third',
children: [{
_id: '446d30905d7e2d1d5169181d',
name: '3child',
children: []
}, {
_id: '446d30915d7e2d1d5169181d',
name: '3child2',
children: [{
_id: '546d30905d7edd1d2569181d',
name: 'second2',
children: []
}]
}]
}, {
_id: '546d30995d7edd1d5169181d',
name: 'fourth',
children: []
}]
This is a truncated document that's being stored in MongoDB using materialized path. The issue is that I need to add a 'sorting' ability, so nodes in the same root can be sorted.
I want to iterate this tree and apply a sort_value such as node['sort_value'] = 0, etc.
Each level will have it's own sort order, starting at 0.
I can simply iterate the tree recursively:
function iterate(items) {
_.each(items, function(page, key) {
if (items.children.length > 0) {
iterate(items.children);
}
});
}
However, I can't figure out how to keep track of the sort orders and also update the object's to include the sort_value field.
Any help would be greatly appreciated! Thank you
I did it so that I used array key for sorting and "synchronized" it with object property (because I needed it saved to DB and restored after) and it works as a charm :)
So something like this, pseudo:
var unsorted = [
0:{"sort_key": "0", "data":"dataaa 0"},
1:{"sort_key": "1", "data":"dataaa 1"},
...
n:{"sort_key": "n", "data":"dataaa n"}
];
function_sort(unsorted){
...
return sorted = [
0:{"sort_key": "n", "data":"dataaa y"},
1:{"sort_key": "44", "data":"dataaa x"},
...
n:{"sort_key": "0", "data":"dataaa z"}
];
}
save = function_save(sorted){
...update sort_key as array key...
return for_saving;
}

Categories