Итерировать конкретное свойство вложенного объекта и передавать в массив - PullRequest
2 голосов
/ 14 марта 2019

Имейте объект, показанный ниже, где мне нужно перебирать каждое свойство объекта, чтобы найти 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"
  }
]

Я попробовал приведенный ниже код, но он возвращает ноль из-за проблемы с областью видимости:

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 ]

3 голосов
/ 14 марта 2019

Вы можете выполнять итерации с помощью генератора 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));
2 голосов
/ 14 марта 2019

Вы можете сделать это рекурсивно с использованием синтаксиса и деструктуризации.

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);
0 голосов
/ 14 марта 2019

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);
0 голосов
/ 14 марта 2019

Рекурсивная функция, которая будет копировать каждую клавишу, которая не соответствует данной, которая используется для углубления.

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));
...