admin管理员组文章数量:1416651
I have following array of objects with nested arrays in it. I wanted to traverse through those arrays and extract all those impact information to separate array:
this is how my input data looks like:
{
"violations": [{
"impact": "serious",
"nodes": [{
"any": [{
"impact": "critical"
},
{
"impact": "serious"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "minor"
}]
}]
},
{
"impact": "serious",
"nodes": [{
"any": [{
"impact": "serious"
},
{
"impact": "minor"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "serious"
}]
}]
},
{
"impact": "serious",
"nodes": [{
"any": [{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "moderate"
}]
},
{
"any": [{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "moderate"
}]
}
]
}
]
}
expected output:
[
{
"impact": "serious"
},
{
"impact": "critical"
},
{
"impact": "serious"
},
{
"impact": "moderate"
},
{
"impact": "minor"
},
{
"impact": "serious"
},
{
"impact": "serious"
},
{
"impact": "minor"
},
......
]
I'm currently trying with forEach loop like below:
const results = [];
violations.forEach(({ nodes, impact }) => {
results.push({ impact });
// flattening nodes
nodes.forEach(({ any, all, none }) => {
any.forEach((v) => results.push(v));
all.forEach((v) => results.push(v));
none.forEach((v) => results.push(v));
});
});
is there any better and shorter way to do the same?
I have following array of objects with nested arrays in it. I wanted to traverse through those arrays and extract all those impact information to separate array:
this is how my input data looks like:
{
"violations": [{
"impact": "serious",
"nodes": [{
"any": [{
"impact": "critical"
},
{
"impact": "serious"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "minor"
}]
}]
},
{
"impact": "serious",
"nodes": [{
"any": [{
"impact": "serious"
},
{
"impact": "minor"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "serious"
}]
}]
},
{
"impact": "serious",
"nodes": [{
"any": [{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "moderate"
}]
},
{
"any": [{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "moderate"
}]
}
]
}
]
}
expected output:
[
{
"impact": "serious"
},
{
"impact": "critical"
},
{
"impact": "serious"
},
{
"impact": "moderate"
},
{
"impact": "minor"
},
{
"impact": "serious"
},
{
"impact": "serious"
},
{
"impact": "minor"
},
......
]
I'm currently trying with forEach loop like below:
const results = [];
violations.forEach(({ nodes, impact }) => {
results.push({ impact });
// flattening nodes
nodes.forEach(({ any, all, none }) => {
any.forEach((v) => results.push(v));
all.forEach((v) => results.push(v));
none.forEach((v) => results.push(v));
});
});
is there any better and shorter way to do the same?
Share Improve this question edited Dec 10, 2021 at 6:42 PeterKA 24.7k5 gold badges27 silver badges52 bronze badges asked Dec 10, 2021 at 5:52 Web3guyWeb3guy 231 silver badge3 bronze badges 1- There are shorter ways to do the same, but at the expense of readability. I think your code is better than any of the answers below, because it is easy to see what happens and therefore easier to maintain with low risk of introducing bugs. That is much more important than saving a few lines of code. – www.admiraalit.nl Commented Dec 10, 2021 at 7:22
5 Answers
Reset to default 2You can achieve your result like below snippet:
const items = {
"violations": [
{
"impact": "serious",
"nodes": [
{
"any": [
{
"impact": "critical"
},
{
"impact": "serious"
}
],
"all": [
{
"impact": "moderate"
}
],
"none": [
{
"impact": "minor"
}
]
}
]
},
{
"impact": "serious",
"nodes": [
{
"any": [
{
"impact": "serious"
},
{
"impact": "minor"
}
],
"all": [
{
"impact": "moderate"
}
],
"none": [
{
"impact": "serious"
}
]
}
]
},
{
"impact": "serious",
"nodes": [
{
"any": [
{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [
{
"impact": "moderate"
}
],
"none": [
{
"impact": "moderate"
}
]
},
{
"any": [
{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [
{
"impact": "moderate"
}
],
"none": [
{
"impact": "moderate"
}
]
}
]
}
]
}
const newItems = items.violations.reduce((acc, {impact, nodes})=> {
acc.push({impact});
nodes.forEach(item => {
Object.keys(item).forEach(key => {
acc.push(...item[key]);
})
})
return acc
}, []);
console.log(newItems);
This should do it:
const impacts = data.violations.map(({impact,nodes}) =>
[{impact}, ...nodes.map(({any,all,none}) => [...any, ...all, ...none]).flat()]
)
.flat();
const data = {
"violations": [{
"impact": "serious",
"nodes": [{
"any": [{
"impact": "critical"
},
{
"impact": "serious"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "minor"
}]
}]
},
{
"impact": "serious",
"nodes": [{
"any": [{
"impact": "serious"
},
{
"impact": "minor"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "serious"
}]
}]
},
{
"impact": "serious",
"nodes": [{
"any": [{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "moderate"
}]
},
{
"any": [{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "moderate"
}]
}
]
}
]
};
const impacts = data.violations.map(({impact,nodes}) =>
[{impact}, ...nodes.map(({any,all,none}) => [...any, ...all, ...none]).flat()]
)
.flat();
console.log( impacts );
OR: A slight modification to yours
let results = [];
data.violations.forEach(({nodes,impact}) => {
results.push({impact});
// flattening nodes
nodes.forEach(({any,all,none}) =>
results.concat(...[...any, ...all, ...none])
);
});
const data = {
"violations": [{
"impact": "serious",
"nodes": [{
"any": [{
"impact": "critical"
},
{
"impact": "serious"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "minor"
}]
}]
},
{
"impact": "serious",
"nodes": [{
"any": [{
"impact": "serious"
},
{
"impact": "minor"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "serious"
}]
}]
},
{
"impact": "serious",
"nodes": [{
"any": [{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "moderate"
}]
},
{
"any": [{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [{
"impact": "moderate"
}],
"none": [{
"impact": "moderate"
}]
}
]
}
]
};
let results = [];
data.violations.forEach(({ nodes, impact }) => {
results.push({ impact });
// flattening nodes
nodes.forEach(({ any, all, none }) =>
results = results.concat(...[...any, ...all, ...none])
);
});
console.log( results );
here is your solution
let output = []
function recursion(obj, op) {
if (typeof obj === 'object') {
if (obj.impact) {
op.push({ impact: obj.impact })
}
for (var key in obj) {
recursion(obj[key], op)
}
}
return
}
recursion(obj, output)
console.log(output)
Runnable code is
let obj = {
"violations": [
{
"impact": "serious",
"nodes": [
{
"any": [
{
"impact": "critical"
},
{
"impact": "serious"
}
],
"all": [
{
"impact": "moderate"
}
],
"none": [
{
"impact": "minor"
}
]
}
]
},
{
"impact": "serious",
"nodes": [
{
"any": [
{
"impact": "serious"
},
{
"impact": "minor"
}
],
"all": [
{
"impact": "moderate"
}
],
"none": [
{
"impact": "serious"
}
]
}
]
},
{
"impact": "serious",
"nodes": [
{
"any": [
{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [
{
"impact": "moderate"
}
],
"none": [
{
"impact": "moderate"
}
]
},
{
"any": [
{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [
{
"impact": "moderate"
}
],
"none": [
{
"impact": "moderate"
}
]
}
]
}
]
}
let output = []
function recursion(obj, op) {
if (typeof obj === 'object') {
if (obj.impact) {
op.push({ impact: obj.impact })
}
for (var key in obj) {
recursion(obj[key], op)
}
}
return
}
recursion(obj, output)
console.log(output)
I feel like recursion is going to be your friend on this one, the advantage being that it will continue to work no matter how much you change your levels of nesting.
This will return an array like what you are looking for:
function extractImpactInformation(data) {
const results = [];
if (typeof data === 'object') {
if (data['impact']) {
results.push({ 'impact': data['impact'] });
}
for (const key in data) {
results.push(...extractImpactInformation(data[key]));
}
}
return results;
}
const testData = {
"violations": [
{
"impact": "serious",
"nodes": [
{
"any": [
{
"impact": "critical"
},
{
"impact": "serious"
}
],
"all": [
{
"impact": "moderate"
}
],
"none": [
{
"impact": "minor"
}
]
}
]
},
{
"impact": "serious",
"nodes": [
{
"any": [
{
"impact": "serious"
},
{
"impact": "minor"
}
],
"all": [
{
"impact": "moderate"
}
],
"none": [
{
"impact": "serious"
}
]
}
]
},
{
"impact": "serious",
"nodes": [
{
"any": [
{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [
{
"impact": "moderate"
}
],
"none": [
{
"impact": "moderate"
}
]
},
{
"any": [
{
"impact": "critical"
},
{
"impact": "critical"
}
],
"all": [
{
"impact": "moderate"
}
],
"none": [
{
"impact": "moderate"
}
]
}
]
}
]
}
function extractImpactInformation(data) {
const results = [];
if (typeof data === 'object') {
if (data['impact']) {
results.push({ 'impact': data['impact'] });
}
for (const key in data) {
results.push(...extractImpactInformation(data[key]));
}
}
return results;
}
console.log(extractImpactInformation(testData));
you can create a reducer function like this to group your impact data.
const impactReducer = (acc, {impact, nodes}) => {
if (impact) acc.push({impact});
nodes?.forEach(node => Object.keys(node).forEach(key => node[key].reduce(impactReducer, acc)));
return acc;
};
const impacts = items.violations.reduce(impactReducer, []);
本文标签: javascriptLooping through nested array of objectsStack Overflow
版权声明:本文标题:javascript - Looping through nested array of objects - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745255918a2650100.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论