Loop through objects of objects in js [duplicate] - javascript

This question already has answers here:
What is the difference between ( for... in ) and ( for... of ) statements?
(18 answers)
Closed last year.
I have a data like this:
{
"countries": {
"US": {
"details": {
"code": 1,
"population": ""
},
"people": [
{
"name": ""
},
{
"name": ""
}
]
},
"UK": {
"details": {
"code": 44,
"population": ""
},
"people": [
{
"name": ""
},
{
"name": ""
}
]
}
}
}
I want to loop through it and extract people so I can loop through the people and display them on the site.
var countries = {
"countries": {
"US": {
"details": {
"code": 1,
"population": ""
},
"people": [
{
"name": ""
},
{
"name": ""
}
]
},
"UK": {
"details": {
"code": 44,
"population": ""
},
"people": [
{
"name": ""
},
{
"name": ""
}
]
}
}
}
for (let [key, value] of Object.entries(countries.countries)) {
//console.log(value);
for (var people in value.people) {
console.log(people);
}
}
But I keep getting 0, 1, how can I get the value of people array?

For array (and other data structures implementing the iterable interface) it's for...of, not for...in (which is for iterating over keys of an object).
var countries = {
"countries": {
"US": {
"details": {
"code": 1,
"population": ""
},
"people": [{
"name": ""
},
{
"name": ""
}
]
},
"UK": {
"details": {
"code": 44,
"population": ""
},
"people": [{
"name": ""
},
{
"name": ""
}
]
}
}
}
for (let [key, value] of Object.entries(countries.countries)) {
for (let people of value.people) {
console.log(people);
}
}

const obj = {
"countries": {
"US": {
"details": {
"code": 1,
"population": ""
},
"people": [
{
"name": ""
},
{
"name": ""
}
]
},
"UK": {
"details": {
"code": 44,
"population": ""
},
"people": [
{
"name": ""
},
{
"name": ""
}
]
}
}
}
for (let key in obj.countries) {
console.log(obj.countries[key].people);
}

Related

How do I destructure this deep nested json objects and map it in JS

I have a nested array like below. There are about 100 de objects in the array. The de objects also have deg[0] array but most likely I will only have the first index. Now the trick is that the de are subset of deg. Which means each deg can have say 10 de. How can I retrieve the deg and there associated de and map it into a new array like:
newArray = [
deg1: [
{de1},
{de2}
],
deg2: [
{de1},
{de2}
]
]
Here is my nested array. I posted four but the list is over a 100.
{
"name": "Report",
"id": "2YYUEZ6I1r9",
"dse1": [
{
"de1": {
"name": "Number",
"id": "HjMOngg3kuy",
"de1-av": [
{
"value": "FHaQMPv9zc7",
"attribute": {
"id": "uwVkIP7PZDt"
}
},
{
"value": "something",
"attribute": {
"id": "FHaQMPv9zc7"
}
}
],
"deg1": [
{
"name": "TB",
"id": "2XJB1JO9qX8"
}
]
}
},
{
"de2": {
"name": "Number of",
"id": "a3dtGETTawy",
"de2-av": [
{
"value": "FHaQMPv9zc7",
"attribute": {
"id": "uwVkIP7PZDt"
}
},
{
"value": "something",
"attribute": {
"id": "FHaQMPv9zc7"
}
}
],
"deg1": [
{
"name": "Secondary",
"id": "w99RWzXHgtw"
}
]
}
},
{
"de1": {
"name": "Number of",
"id": "a3dtGETTawy",
"de1av": [
{
"value": "FHaQMPv9zc7",
"attribute": {
"id": "uwVkIP7PZDt"
}
},
{
"value": "something",
"attribute": {
"id": "FHaQMPv9zc7"
}
}
],
"deg2": [
{
"name": "Secondary",
"id": "w99RWzXHgtw"
}
]
}
},
{
"de2": {
"name": "Number of",
"id": "a3dtGETTawy",
"de2av": [
{
"value": "FHaQMPv9zc7",
"attribute": {
"id": "uwVkIP7PZDt"
}
},
{
"value": "something",
"attribute": {
"id": "FHaQMPv9zc7"
}
}
],
"deg2": [
{
"name": "Tertiary",
"id": "w99RWzXHgtw"
}
]
}
}
]
}
Group array of objects by property (this time a property to be matched by a reg exp) using Array.reduce.
Update: Ignoring missing keys.
var input={name:"Report",id:"2YYUEZ6I1r9",dse1:[{de1:{name:"Number",id:"HjMOngg3kuy","de1-av":[{value:"FHaQMPv9zc7",attribute:{id:"uwVkIP7PZDt"}},{value:"something",attribute:{id:"FHaQMPv9zc7"}}],deg1:[{name:"TB",id:"2XJB1JO9qX8"}]}},{de2:{name:"Number of",id:"a3dtGETTawy","de2-av":[{value:"FHaQMPv9zc7",attribute:{id:"uwVkIP7PZDt"}},{value:"something",attribute:{id:"FHaQMPv9zc7"}}],deg1:[{name:"Secondary",id:"w99RWzXHgtw"}]}},{de1:{name:"Number of",id:"a3dtGETTawy",de1av:[{value:"FHaQMPv9zc7",attribute:{id:"uwVkIP7PZDt"}},{value:"something",attribute:{id:"FHaQMPv9zc7"}}],deg2:[{name:"Secondary",id:"w99RWzXHgtw"}]}},{de2:{name:"Number of",id:"a3dtGETTawy",de2av:[{value:"FHaQMPv9zc7",attribute:{id:"uwVkIP7PZDt"}},{value:"something",attribute:{id:"FHaQMPv9zc7"}}],deg2:[{name:"Tertiary",id:"w99RWzXHgtw"}]}}]}
var reg = new RegExp("^de[0-9]+$");
var reg2 = new RegExp("^deg[0-9]+$");
let obj = input['dse1'].reduce(function(agg, item) {
// do your group by logic below this line
var key = Object.keys(item).find(function(key) {
return key.match(reg) ? key : null;
})
if (key) {
var key2 = Object.keys(item[key]).find(function(key) {
return key.match(reg2) ? key : null;
})
agg[key] = agg[key] || [];
if (key2) {
var to_push = {}
to_push[key2] = item[key][key2]
agg[key].push(to_push)
}
}
// do your group by logic above this line
return agg
}, {});
console.log(obj)
.as-console-wrapper {
max-height: 100% !important;
}

Search a Javascript Object for the position of a specific ID? [duplicate]

This question already has answers here:
Find by key deep in a nested array
(21 answers)
Closed 4 years ago.
I have a Javascript object with lots of different sections. How can I search through all of the sections to find the position of a specific ID? The ID's that I am searching for are not in a specific location, and can be located in any of the tree branches.
For example, I am searching for this ID:
xobmnbjxg0g_1527269346261
And I am trying to output the position of that ID, which would be this:
app['structure'][0]['if-children'][0]['id']
My Javascript Object:
var app = {
"structure": [
{
"id": "0",
"type":"IF",
"parameters": [
{
"id": "xobmnbjxg0g_1527269346260",
"type": "field",
"value": "CV_TEST_SPOT1X"
},
{
"id": "2",
"type": "operator",
"value": "="
},
{
"id": "3",
"type": "field",
"value": "North America"
}
],
"if-children": [
{
"id": "xobmnbjxg0g_1527269346261",
"type":"IF",
"parameters": [
{
"id": "1",
"type": "field",
"value": "CV_TEST_SPOT1"
},
{
"id": "2",
"type": "operator",
"value": "="
},
{
"id": "3",
"type": "field",
"value": "North America"
}
],
"if-children":[
],
"else-children":[
]
}
],
"else-children":[
{
"id": "xobmnbjxg0g_1527269346262",
"type":"IF",
"parameters": [
{
"id": "1",
"type": "field",
"value": "CV_TEST_SPOT1"
},
{
"id": "2",
"type": "operator",
"value": "="
},
{
"id": "3",
"type": "field",
"value": "North America"
}
],
"if-children":[
{
"id":"xobmnbjxg0g_152726934626X"
}
],
"else-children":[
{
"id":"xobmnbjxg0g_152726934626Y"
}
]
}
]
},
{
"id": "xobmnbjxg0g_1527269346263",
"type":"IF",
"parameters": [
[
{
"id": "1",
"type": "field",
"value": "CV_TEST_SPOT1"
}
]
],
"if-children": [
{
"id": "xobmnbjxg0g_1527269346264",
"type":"IF",
"parameters": [
[
{
"id": "1",
"type": "field",
"value": "CV_TEST_SPOT1"
}
]
],
"if-children":[
{
"id": "xobmnbjxg0g_1527269346265",
"type":"IF",
"parameters": [
{
"id": "1",
"type": "field",
"value": "CV_TEST_SPOT1"
}
],
"if-children":[
{
"id":"xobmnbjxg0g_1527269346266"
}
],
"else-children":[
{
"id":"xobmnbjxg0g_1527269346267"
}
]
}
],
"else-children":[
{
"id":"xobmnbjxg0g_1527269346268"
}
]
}
],
"else-children":[
{
"id":"xobmnbjxg0g_1527269346269"
}
]
}
]
};
Interesting puzzle/question.
pretty sure there are some edge cases im missing but this seems to pass some tests.
function is(obj, type){
return Object.prototype.toString.call(obj) === `[object ${type}]`;
}
function findPosition(obj, mykey, myval, res){
if(is(obj, "Object")){
if(mykey in obj && obj[mykey] === myval){
res.tree.push(mykey);
res.found = true;
} else {
for( let key in obj){
if(res.found) break;
res.tree.push(key);
findPosition(obj[key], mykey, myval, res);
}
if(!res.found) res.tree.pop();
}
} else if(is(obj, "Array")){
for(let i = 0; i < obj.length; i++){
if(res.found) break;
res.tree.push(i);
findPosition(obj[i], mykey, myval, res);
}
if(!res.found) res.tree.pop();
} else {
res.tree.pop();
}
return res;
}
Usage and output
findPosition([{one: { two: [{id: [{id:'my'}]}]}}], "id", "mys", {tree:[], found: false})
> tree: Array(0), found: false}
findPosition([{one: { two: [{id: [{id:'my'}]}]}}], "id", "my", {tree:[], found: false})
> {found: true, tree: [0, "one", "two", 0, "id", 0, "id"]}
For finding if current obj you are iterating over is an Array you can also use Array.isArray

Create new javascript object from 2 JSON objects grouped by id

I have below dynamic nested JSON object arrays and I wanted to get the desired output with JavaScript grouped by id from both.
First Array:
[
{
"id": "11",
"name": "emp1",
"location": [
{ "name": "abc", "id": "lc1" }
]
},
{
"id": "11",
"name": "emp2",
"location": [
{ "name": "abc", "id": "lc1" },
]
},
{
"id": "22",
"name": "emp3",
"location": [
{ "name": "xyz", "id": "lc2" }
]
}
]
Second array like below.
[
{
"name": "sub1",
"id": "11"
...
},
{
"name": "sub1.1",
"id": "11"
...
},
{
"name": "sub2",
"id": "22"
...
}
]
Desired Output:
[
{
"id": "11",
"first": [{"name": "emp1"},
{"name": "emp2"}],
"second": [{"name": "sub1"},{"name": "sub1.1"}],
"location": [{"name": "abc"}]
},
{
"id": "22",
"first": [{"name": "emp3"}],
"second": [{"name": "sub2"}],
"location": [{"name": "xyz"}]
}
]
How to get the desired output like above using javascript/angularjs?
I would do it using the amazing Array#reduce function.
Note that I have named your first array as a1, second as a2 and result as res.
a1.reduce(function(arr, obj) {
var existing = arr.filter(function(res) {
return res.id === obj.id
})[0]
if (existing) {
existing.first.push({
name: obj.name
})
} else {
var second = a2.filter(function(res) {
return res.id === obj.id
})
var secondObj = second.length ? second.map(function(sec) {
return {
name: sec.name
};
}) : []
arr.push({
id: obj.id,
first: [{
name: obj.name
}],
second: secondObj,
location: obj.location
})
}
return arr;
}, [])
Here's the working snippet. Take a look!
var a1 = [{
"id": "11",
"name": "emp1",
"location": [{
"name": "abc",
"id": "lc1"
}]
},
{
"id": "11",
"name": "emp2",
"location": [{
"name": "abc",
"id": "lc1"
}]
},
{
"id": "22",
"name": "emp3",
"location": [{
"name": "xyz",
"id": "lc2"
}]
}
]
var a2 = [{
"name": "sub1",
"id": "11"
}, {
"name": "sub1.1",
"id": "11"
},
{
"name": "sub2",
"id": "22"
}
]
var res = a1.reduce(function(arr, obj) {
var existing = arr.filter(function(res) {
return res.id === obj.id
})[0]
if (existing) {
existing.first.push({
name: obj.name
})
} else {
var second = a2.filter(function(res) {
return res.id === obj.id
})
var secondObj = second.length ? second.map(function(sec) {
return {
name: sec.name
};
}) : []
arr.push({
id: obj.id,
first: [{
name: obj.name
}],
second: secondObj,
location: obj.location
})
}
return arr;
}, [])
console.log(res)
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}
var red1 = [{
"id": "11",
"name": "emp1",
"location": [{
"name": "abc",
"id": "lc1"
}]
},
{
"id": "11",
"name": "emp2",
"location": [{
"name": "abc",
"id": "lc1"
}]
},
{
"id": "22",
"name": "emp3",
"location": [{
"name": "xyz",
"id": "lc2"
}]
}
]
var b = [{
"name": "sub1",
"id": "11"
},
{
"name": "sub2",
"id": "22"
}
]
var identication = {}
var result = []
red1.forEach(function(val) {
if (val['id'] in identication) {
var t = {}
t['name'] = val['name']
result[identication[val['id']]]['first'].push(t)
} else {
var t = {}
t['name'] = val['name']
val['first'] = []
val['first'].push(t)
delete val['name']
var identity = result.push(val)
identication[val['id']] = identity - 1;
}
})
b.forEach(function(d) {
if (d['id'] in identication) {
var t = {
'name': d['name']
}
if (!('second' in result[identication[d['id']]])) {
result[identication[d['id']]]['second'] = []
}
result[identication[d['id']]]['second'].push(t)
} else {
var t = {}
for (key in d) {
if (key == 'name')
continue
t[key] = d[key]
}
t['second'] = [{
'name': d['name']
}]
var identity = result.push(t)
identication[d['id']] = identity - 1;
}
})
console.log(result)

How to make subarrays containing a same string from an array?

I have an array like this :
[
{
"title": "name",
"value": ""
},
{
"title": "version",
"value": ""
},
{
"title": "inventory_name",
"value": ""
},
{
"title": "inventory_version",
"value": ""
},
{
"title": "differed",
"value": ""
},
{
"title": "differed_name",
"value": ""
},
{
"title": "accept_error_while_reboot",
"value": ""
},
{
"title": "setup_check",
"value": ""
},
{
"title": "setup_install",
"value": ""
},
{
"title": "setup_install_partial",
"value": ""
},
{
"title": "params_install",
"value": ""
},
{
"title": "params_install_partial",
"value": ""
},
{
"title": "results_install_ok",
"value": ""
},
{
"title": "results_install_reboot_defered",
"value": ""
},
{
"title": "results_install_reboot_immediate",
"value": ""
},
{
"title": "results_install_partial_ok",
"value": ""
},
{
"title": "results_install_partial_reboot_defered",
"value": ""
},
{
"title": "results_install_partial_reboot_immediate",
"value": ""
}
];
Is it possible to make subarrays that contains the same title field string ?
For example in this case , I will have :
array1 = [
{
"title": "differed",
"value": ""
},
{
"title": "differed_name",
"value": ""
}
]
array2 = [
{
"title": "setup_check",
"value": ""
},
{
"title": "setup_install",
"value": ""
},
{
"title": "setup_install_partial",
"value": ""
}
]
and so on...
In case of single elements , I should have :
[
{
"title": "name",
"value": ""
}
]
I'm searching for a generic approach.
I know I can use, for example, indexOf('results') with filter function, however I'd like if it's possible to avoid the hardcode since it's not always the same titles.
Any ideas ?
Fiddle
You can use an object to group similar items:
var groups = {};
parameter_list.forEach(function(p){
var key = p.title.split('_')[0];
if(!groups[key]) {
groups[key] = [];
}
groups[key].push(p);
});
Working demo:
http://jsfiddle.net/t459o6v1/3/
Group the data with .reduce()
var groups = data.reduce(function(result, currentValue) {
var key = currentValue.title.split("_")[0];
if (typeof result[key] === "undefined") {
result[key] = [];
}
result[key].push(currentValue);
return result;
}, {});
And then (if needed) use .map() to transform the object into "subarrays"
var subArrays = Object.keys(groups).map(function(key) {
return groups[key];
});
var data = [{
"title": "name",
"value": ""
}, {
"title": "version",
"value": ""
}, {
"title": "inventory_name",
"value": ""
}, {
"title": "inventory_version",
"value": ""
}, {
"title": "differed",
"value": ""
}, {
"title": "differed_name",
"value": ""
}, {
"title": "accept_error_while_reboot",
"value": ""
}, {
"title": "setup_check",
"value": ""
}, {
"title": "setup_install",
"value": ""
}, {
"title": "setup_install_partial",
"value": ""
}, {
"title": "params_install",
"value": ""
}, {
"title": "params_install_partial",
"value": ""
}, {
"title": "results_install_ok",
"value": ""
}, {
"title": "results_install_reboot_defered",
"value": ""
}, {
"title": "results_install_reboot_immediate",
"value": ""
}, {
"title": "results_install_partial_ok",
"value": ""
}, {
"title": "results_install_partial_reboot_defered",
"value": ""
}, {
"title": "results_install_partial_reboot_immediate",
"value": ""
}];
var groups = data.reduce(function(result, currentValue) {
var key = currentValue.title.split("_")[0];
if (typeof result[key] === "undefined") {
result[key] = [];
}
result[key].push(currentValue);
return result;
}, {});
var subArrays = Object.keys(groups).map(function(key) {
return groups[key];
});
console.log(JSON.stringify(subArrays));
I came up with a solution using Immutable.JS, but you could probably do something similar with lodash or underscore. Note that this is a functional version, not imperative.
First create a function that gets the prefix:
function getPrefix(name) {
var substr = name.substring(0, name.indexOf('_'))
return substr ? substr : name;
}
Then use the groupBy function:
Immutable.fromJS(arr).groupBy(element => getPrefix( element['title']))
.toJS();
This will give you an array of arrays with the title as it's key.

Jquery : transform nested json object to another json object

In javascript/jquery how do i achieve following
old_dataset = [
{
"dob": "xyz",
"name": {
"first": " abc",
"last": "lastname"
},
"start_date": {
"moth": "2",
"day": "5",
"year": 1
},
"children": [
{
"child": {
"id": "1",
"desc": "first child"
}
},
{
"child": {
"id": "2",
"desc": "second child"
}
}
]
},
{
"dob": "er",
"name": {
"first": " abc",
"last": "txt"
},
"start_date": {
"moth": "2",
"day": "5",
"year": 1
},
"children": [
{
"child": {
"id": "1",
"desc": "first child"
}
},
{
"child": {
"id": "2",
"desc": "second child"
}
}
]
}
]
Using jquery iterate over the above and change to following
new_dataset = [
{
"dob":"xyz",
"name": <first and last name values>
"start_date":<value of month day year>,
"children": [ {
child_id :1,
child_id : 2
},
]
},{
"dob":"er",
"name": <first and last name values>
"start_date":<value of month day year>,
"children": [ {
child_id :1,
child_id : 2
},
]
}]
If someone can give the code to transform the data it would help me to understand the iteration
You could do something like:
function transformDataset(oldDataset) {
var newDataset = [];
var newObj;
for (var i = 0; i < oldDataset.length; i++) {
newObj = transformObj(oldDataset[i]);
newDataset.push(newObj);
}
return newDataset;
}
function transformObj(obj) {
var children = obj.children;
obj.name = obj.name.first + ' ' + obj.name.last;
obj.start_date = obj.start_date.month + ' ' + obj.start_date.day + ' ' + obj.start_date.year;
obj.children = [];
for (var i = 0; i < children.length; i++) {
obj.children.push(children[i].child.id);
}
return obj;
}
var new_dataset = transformDataset(old_dataset);
Note that new_dataset will have an array of child id instead of an object with multiple child_id properties.
You also had a typo in old_dataset.start_date.month (was written moth)(or maybe that was intentional).
use map first to iterate the array data (old_dataset), replace element name & start_date with new value then return the array
const old_dataset = [
{
"dob": "xyz",
"name": {
"first": " abc",
"last": "lastname"
},
"start_date": {
"moth": "2",
"day": "5",
"year": 1
},
"children": [
{
"child": {
"id": "1",
"desc": "first child"
}
},
{
"child": {
"id": "2",
"desc": "second child"
}
}
]
},
{
"dob": "er",
"name": {
"first": " abc",
"last": "txt"
},
"start_date": {
"moth": "2",
"day": "5",
"year": 1
},
"children": [
{
"child": {
"id": "1",
"desc": "first child"
}
},
{
"child": {
"id": "2",
"desc": "second child"
}
}
]
}
]
let new_dataset = old_dataset.map((arr) => {
arr.name = `${arr.name.first} ${arr.name.last}`
arr.start_date = `${arr.start_date.moth} ${arr.start_date.day} ${arr.start_date.year}`
return arr
})
console.log(new_dataset)

Categories

Resources