javascript - Looping through nested array of objects - Stack Overflow

I have following array of objects with nested arrays in it. I wanted to traverse through those arrays a

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
Add a ment  | 

5 Answers 5

Reset to default 2

You 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, []);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745255919a4618955.html

相关推荐

  • javascript - Looping through nested array of objects - Stack Overflow

    I have following array of objects with nested arrays in it. I wanted to traverse through those arrays a

    1小时前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信