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