【问题标题】:Looping though Object inside object in vanilla JS在香草JS中循环对象内部的对象
【发布时间】:2019-03-25 15:09:40
【问题描述】:

我得到了附件中的 Json 结果。它是一个里面有物体的物体。我在一个数组中转换了主对象,现在我可以毫无问题地循环它。但是,我无法获取内部对象内的信息。顺便说一句,在对象内部我可以得到任意数量的子对象,从 0 到未定义。

我需要在 Vue 项目中使用它。但由于这是纯 JS,我制作了一个文件仅用于测试目的。如果它在 JS 中工作,我可以让它在 Vue 中工作。

我尝试将对象转换为数组(非常有效,并且包含在代码中),但我无法循环并再次转换。

let dados = {
  et1: {
      at:"Lorem ipsum dolor sit amet, consectetur",
      st:"Done",
      di:"01/19",
      df:"03/19",
      vl:"10000",
    sub1:{
      at:"Integer ligula purus, convallis convallis",
      st:"Done",
      di:"01/19",
      df:"03/19",
      vl:"8000" 
    },
    sub2:{
      at:"Mauris felis tellus, ullamcorper eu",
      st:"Done",
      di:"01/19",
      df:"03/19",
      vl:"2000" 
    }
  },
  et2: {
      at:"Nunc in urna ultricies sapien",
      st:"Post",
      di:"01/19",
      df:"03/19",
      vl:"40000"
  },
  et3: {
      at:"Phasellus varius rhoncus urna, nec",
      st:"Execution",
      di:"01/19",
      df:"03/19",
      vl:"4000",
    sub1:{
      at:"Phasellus varius rhoncus urna, nec",
      st:"Execution",
      di:"01/19",
      df:"03/19",
      vl:"2000" 
    }
  }
}

console.log(dados)

Object.entries(dados).forEach(([key, value]) => {
 console.log(value);

 let fields = Object.values(value);
 console.log(fields)
});

使用这段代码,我得到了一个数组,但内部对象没有改变,正如预期的那样。我只需要找到如何转换内部对象。也许在循环中有一个循环(我认为这是一种不好的做法,不是吗?)

【问题讨论】:

  • 到目前为止你尝试过什么?请出示您的代码。
  • “也许在一个循环内有一个循环”:是的。 “我认为这是一种不好的做法,不是吗?”:没有
  • @Soviut 有代码,在sn-p的底部
  • 或者你可以尝试递归,取决于用例。如果它只有 2 个级别,那么只需使用 2 个 for 语句
  • 预期输出是多少?您可能必须在 forEach 内执行 Object.entries(value),具体取决于您要执行的操作

标签: javascript arrays loops object


【解决方案1】:

对于任意深度的对象,您可以创建一个递归函数。它打印常规值并将对象传递回函数。这将以深度优先顺序打印所有值。

let dados = {et1: {at:"Lorem ipsum dolor sit amet, consectetur",st:"Done",di:"01/19",df:"03/19",vl:"10000",sub1:{at:"Integer ligula purus, convallis convallis",st:"Done",di:"01/19",df:"03/19",vl:"8000" },sub2:{at:"Mauris felis tellus, ullamcorper eu",st:"Done",di:"01/19",df:"03/19",vl:"2000" }},et2: {at:"Nunc in urna ultricies sapien",st:"Post",di:"01/19",df:"03/19",vl:"40000"},et3: {at:"Phasellus varius rhoncus urna, nec",st:"Execution",di:"01/19",df:"03/19",vl:"4000",sub1:{at:"Phasellus varius rhoncus urna, nec",st:"Execution",di:"01/19",df:"03/19",vl:"2000" }}}
  
function printValues(obj){
    Object.entries(obj).forEach(([key, value]) => {
        if (typeof value == 'object' && value !== null)  printValues(value) // it's an object
        else  console.log(key, ":", value);
       });
}
  
printValues(dados)

如果你想要的话,你应该能够修改基本的想法来制作一个扁平的数组。

【讨论】:

  • 嗯,也许我表达得不好。对我来说,理想的情况是为每个对象(et1、et2、et3)获取一个数组,其中子对象作为一个数组。我正在搞乱所显示的想法,但还没有什么可写的。如果我能找到答案,我会在这里发布:)
  • @Mvotre 在这样的问题中发布您想要的输出很有帮助。
【解决方案2】:

听起来您想遍历dados 中的每个顶级属性并获取子对象(sub1sub2)的所有属性的值。

Object.keys(dados).forEach(key => {
    let val = dados[key];
    if(typeof val === 'object'){
        Object.keys(val).forEach(k => console.log('%s: %s', k, val[k]);
    } else {
        // do something with non-object properties
    }
});

为了清楚起见,在循环内使用循环不一定是坏习惯。事实上,这正是医生在这种情况下所要求的。

【讨论】:

    【解决方案3】:

    您并没有真正说出您需要数据的格式,但我认为这说明了如何从任何级别的对象获取值。我添加了路径/级别变量来帮助说明正在发生的事情,但是您可以(例如)使用它来将对象展平为单个级别(即 { et1.sub1.st : 'Done' } 等)

    
    var values = [],
        path = [],
        level = 0,
        recurse = ob => {
            Object.entries(ob).forEach( ([k,v]) => {
                if(typeof v === 'object'){
                    level++;
                    path.push(k);
                    recurse(v);
                } else {
                    path.push(k);
                    console.log(`level:${level}, key:${k}, path:${path.join('.')} value:${v}`);
                    path.pop();
                }
            });
            level--;
            path.pop();
        };
    recurse(dados);
    
    // output (for ex): level:2, key:st, path:et1.sub1.st value:Done etc...
    

    似乎值得指出的是,这假设您的对象中的所有值都不是数组。如果这是一种可能的情况,您需要为其添加检查。

    【讨论】:

    • 糟糕 - 人们肯定会在这里快速回复!我认为较早的答案涵盖了它-我应该在发布之前刷新页面!
    猜你喜欢
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 2018-05-26
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多