Javascript 迭代特定的嵌套对象属性并推送到数组

Javascript 迭代特定的嵌套对象属性并推送到数组,javascript,arrays,javascript-objects,Javascript,Arrays,Javascript Objects,下面显示了一个对象,我需要遍历每个对象属性来查找nextStep并推送到一个数组。我的输出应该有一个带有所有“nextStep”属性的数组变量 输入: { "Product1": { "stepName": "step1", "stepOutputStatus": "normal", "nextStep": { "stepName": "step2", "stepOutputStatus": "normal", "nextStep"

下面显示了一个对象,我需要遍历每个对象属性来查找nextStep并推送到一个数组。我的输出应该有一个带有所有“nextStep”属性的数组变量

输入:

{
  "Product1": {
    "stepName": "step1",
    "stepOutputStatus": "normal",
    "nextStep": {
      "stepName": "step2",
      "stepOutputStatus": "normal",
      "nextStep": {
        "stepName": "step3",
        "stepOutputStatus": "warning",
        "nextStep": {
          "stepName": "step4",
          "stepOutputStatus": "warning",
          "nextStep": null
        }
      }
    }
  }
}
预期产出:

[
  {
    "stepName": "step2",
    "stepOutputStatus": "normal"
  },
  {
    "stepName": "step3",
    "stepOutputStatus": "warning"
  },
  {
    "stepName": "step4",
    "stepOutputStatus": "warning"
  }
]
我尝试了以下代码,但由于作用域问题,它返回null:

function iterObj(obj) {
  var result = [];
  for (var key in obj) {
    if (
      obj[key] !== null &&
      typeof obj[key] === "object" &&
      key == "nextStep"
    ) {
      var data = this.iterObj(obj[key]);
      result.push(data);
    }
  }
  return result;
}

iterObj(obj);

您可以使用JavaScript生成器进行迭代(不使用递归)。
只需进入下一步,直到没有定义为止

如果您不熟悉
函数*
,请参阅MDN文档

*

const乘积={
步骤名称:“步骤1”,
stepOutputStatus:“正常”,
下一步:{
步骤名称:“步骤2”,
stepOutputStatus:“正常”,
下一步:{
步骤名称:“步骤3”,
stepOutputStatus:“警告”,
下一步:{
步骤名称:“步骤4”,
stepOutputStatus:“警告”,
下一步:空
}
}
}
};
功能*iterObj(obj){
while(对象下一步){
const{stepName,stepOutputStatus}=obj;
产生{stepName,stepOutputStatus};
obj=obj.nextStep;
}
}
常量迭代器=iterObj(乘积);

log(Array.from(迭代器))递归函数,该函数将复制与用于深入的给定键不匹配的每个键

const obj={
“产品1”:{
“步骤名称”:“步骤1”,
“stepOutputStatus”:“正常”,
“下一步”:{
“步骤名称”:“步骤2”,
“stepOutputStatus”:“正常”,
“下一步”:{
“步骤名称”:“步骤3”,
“stepOutputStatus”:“警告”,
“下一步”:{
“步骤名称”:“步骤4”,
“stepOutputStatus”:“警告”,
“下一步”:空
}
}
}
}
};
函数getDataBehindKey(键,ptr){
如果(!ptr){
返回[];
}
返回Object.keys(ptr).reduce((tmp,x)=>{
如果(x==键){
返回[
…tmp,
…getDataBehindKey(key,ptr[x]),
];
}
tmp[0][x]=ptr[x];
返回tmp;
}, [{}]);
}

log(getDataBehindKey('nextStep',obj.Product1))您可以使用扩展语法和解构递归地执行此操作

const data={“Product1”:{“stepName”:“step1”,“stepOutputStatus”:“normal”,“nextStep”:{“stepName”:“step2”,“stepOutputStatus”:“normal”,“nextStep”:{“stepName”:“step3”,“stepOutputStatus”:“warning”,“NextStepStep”:“step4”,“stepOutputStatus”:“warning”,“NextStepStepStep”:“null}}}}
函数handleData({nextStep,…rest}){
常数res=[];
res.push(rest);
如果(下一步){
res.push(…handleData(下一步));
}
返回res;
}
const res=handleData(data.Product1);
控制台日志(res)
let obj={
“产品1”:{
“步骤名称”:“步骤1”,
“stepOutputStatus”:“正常”,
“下一步”:{
“步骤名称”:“步骤2”,
“stepOutputStatus”:“正常”,
“下一步”:{
“步骤名称”:“步骤3”,
“stepOutputStatus”:“警告”,
“下一步”:{
“步骤名称”:“步骤4”,
“stepOutputStatus”:“警告”,
“下一步”:空
}
}
}
}
}
让输出=[];
功能iterObj(obj){
while(obj.nextStep!=null&&obj.hasOwnProperty('nextStep')){
getNextStep(obj.nextStep);
obj=obj.nextStep;
}
}
函数getNextStep(对象){
if(object.hasOwnProperty('nextStep')){
var data={stepName:object.stepName,stepOutputStatus:object.stepOutputStatus};
输出推送(数据);
}
}
iterObj(obj[“Product1]”);

控制台日志(输出)
作为替代方法,也可以将
obj
推送到循环中的一个数组,并在最后返回它。。。然而,生成器也很适合这里…我使用了递归,但突然之间它看起来很难阅读。生成器的想法在我的井中突然出现,在这种情况下,一个简单的
循环就足够了,这就是我投票的主要原因。。。在这种情况下,生成器只是语法糖…谢谢@jonaswillms。我还发现kemikofa是一种优雅的递归方法。@SungM.Kim我承认迭代器非常聪明。我从来没有想过将函数生成器与Array.from结合起来。这是非常优雅的递归。我希望一开始我能写一个这样的递归。。。但它会为每个递归调用创建和销毁一个数组。。。这并不是说性能问题感谢Sung M和Kemicofa的解决方案