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

时间:2019-03-14 14:14:01

标签: javascript arrays javascript-objects

有一个如下所示的对象,我需要遍历每个对象的属性以找到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);

4 个答案:

答案 0 :(得分:3)

您可以使用JavaScript生成器进行迭代(无需使用递归)。
只需进行下一步,直到未定义即可。

如果您不熟悉function *,请参阅MDN文档。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function *

const product = {
  stepName: "step1",
  stepOutputStatus: "normal",
  nextStep: {
    stepName: "step2",
    stepOutputStatus: "normal",
    nextStep: {
      stepName: "step3",
      stepOutputStatus: "warning",
      nextStep: {
        stepName: "step4",
        stepOutputStatus: "warning",
        nextStep: null
      }
    }
  }
};

function* iterObj(obj) {
  while (obj.nextStep) {
    const { stepName, stepOutputStatus } = obj;
    yield { stepName, stepOutputStatus };
    obj = obj.nextStep;
  }
}

const iterator = iterObj(product);
console.log(Array.from(iterator));

答案 1 :(得分:2)

您可以使用扩展语法和解构来递归地执行此操作。

const data={"Product1":{"stepName":"step1","stepOutputStatus":"normal","nextStep":{"stepName":"step2","stepOutputStatus":"normal","nextStep":{"stepName":"step3","stepOutputStatus":"warning","nextStep":{"stepName":"step4","stepOutputStatus":"warning","nextStep":null}}}}}

function handleData({nextStep, ...rest}){
  const res = [];
  res.push(rest);
  if(nextStep){
     res.push(...handleData(nextStep));
  }
  return res;
}

const res = handleData(data.Product1);

console.log(res);

更紧凑的版本:

const data={"Product1":{"stepName":"step1","stepOutputStatus":"normal","nextStep":{"stepName":"step2","stepOutputStatus":"normal","nextStep":{"stepName":"step3","stepOutputStatus":"warning","nextStep":{"stepName":"step4","stepOutputStatus":"warning","nextStep":null}}}}}

const handleData = ({nextStep, ...rest}) => [rest].concat(nextStep ? handleData(nextStep) : []);

const res = handleData(data.Product1);

console.log(res);

答案 2 :(得分:0)

递归函数,它将复制与给定密钥不匹配的每个密钥,该密钥将用于更深层次的开发。

const obj = {
  "Product1": {
    "stepName": "step1",
    "stepOutputStatus": "normal",
    "nextStep": {
      "stepName": "step2",
      "stepOutputStatus": "normal",
      "nextStep": {
        "stepName": "step3",
        "stepOutputStatus": "warning",
        "nextStep": {
          "stepName": "step4",
          "stepOutputStatus": "warning",
          "nextStep": null
        }
      }
    }
  }
};

function getDataBehindKey(key, ptr) {
  if (!ptr) {
    return [];
  }

  return Object.keys(ptr).reduce((tmp, x) => {
    if (x === key) {
      return [
        ...tmp,
        ...getDataBehindKey(key, ptr[x]),
      ];
    }

    tmp[0][x] = ptr[x];

    return tmp;
  }, [{}]);
}

console.log(getDataBehindKey('nextStep', obj.Product1));

答案 3 :(得分:0)

let obj={
  "Product1": {
    "stepName": "step1",
    "stepOutputStatus": "normal",
    "nextStep": {
      "stepName": "step2",
      "stepOutputStatus": "normal",
      "nextStep": {
        "stepName": "step3",
        "stepOutputStatus": "warning",
        "nextStep": {
          "stepName": "step4",
          "stepOutputStatus": "warning",
          "nextStep": null
        }
      }
    }
  }
}

let output=[];


function iterObj(obj) {
  while(obj.nextStep!=null && obj.hasOwnProperty('nextStep')){
    getNextStep(obj.nextStep);
    obj=obj.nextStep;
  }
}

function getNextStep(object){
  if(object.hasOwnProperty('nextStep')){
     var data = {stepName:object.stepName,stepOutputStatus:object.stepOutputStatus};
     output.push(data);
  }
}

iterObj(obj["Product1"]);
console.log(output);