【问题标题】:Array of Arrays to Object RECURSIVELY in plain JS在纯 JS 中递归地对象的数组数组
【发布时间】:2017-01-21 20:42:40
【问题描述】:

在普通 JS(无库)中将数组求解为对象(数组内)的任何递归方法解决方案。基本上我想向自己发送相同的功能。此时我被最后一次迭代覆盖了对象。 我明白了:

{firstName: "Sallito", lastName: "Jordan", age: 16, role: "server"}

虽然我应该得到:

[
    {firstName: 'Eren', lastName: 'Duran', age: 22, role: 'admin'},
    {firstName: 'Sallito', lastName: 'Jordan', age: 16, role: 'server'}
]

原来的数组是:

var array = [
    [
         ['firstName', 'Eren'], ['lastName', 'Duran'], ['age', 22], ['role', 'admin']
    ], 
    [
        ['firstName', 'Sallito'], ['lastName', 'Jordan'], ['age', 16], ['role', 'server']
    ]
];

我目前的解决方案是:

function transformData(array) {
   var obj = {};
     for(var i = 0; i < array.length; i++){        
       for(var j = 0; j < array[i].length; j++){
          for(var k = 0; k < array[i][j].length; k++){
                 if(k === 0){
                 var currentKey = array[i][j][k];
                 var currentValue = array[i][j][k + 1];
                     obj[currentKey] = currentValue;
                 }
          }
      }
  }
     return obj;
  }

请提供递归的想法,因为我知道如何使用 forEach 和 map.reduce 方法来实现。我真的很想学习递归性。谢谢!

【问题讨论】:

  • 请添加原始数据。
  • ..或者如果没有递归解决方案......那么:如何不覆盖我的 obj 而是将新对象添加到旧对象到数组中?
  • 尼娜,一切都在这里......预期的结果,我的代码和我得到的结果。缺少的是: [ [ ['firstName', 'Eren'], ['lastName', 'Duran'], ['age', 22], ['role', 'admin'] ], [ ['firstName', 'Sallito'], ['lastName', 'Jordan'], ['age', 16], ['role', 'server'] ] ] //对不起!
  • 您分享的示例数据是一个简单的 json 对象字符串。它不是数组。有了这些数据,您肯定不需要三个 for 循环。您期望的结果是原始对象数组。所以它在输入数据、逻辑和你想要的输出之间感到困惑。如果您提供要处理的实际数据和所需输出的样本,我们将不胜感激。
  • 递归是什么意思?递归通常用于相同的数据模式(已给出)和相同的处理,但未给出。对于每个级别,您需要不同的初始化、处理/收集和返回。也许你正在寻找这样的东西:gist.github.com/NinaScholz/2a702e1e64b061471ee5

标签: javascript arrays object recursion


【解决方案1】:

使用纯 JS 你可以这样做;

var data = [ [ ['firstName', 'Eren'],
               ['lastName', 'Duran'],
               ['age', 22],
               ['role', 'admin'] ],
             [ ['firstName', 'Sallito'],
               ['lastName', 'Jordan'],
               ['age', 16],
               ['role', 'server'] ]
           ],
 objData = data.map(a => a.reduce((o,t) => Object.assign(o,{[t[0]]:t[1]}),{}));
console.log(objData);

解释:我们在主数组上应用.map(),它的子数组在它的回调中被分配给a参数,每一轮都一个接一个。所以第一轮a就是;

[ ['firstName', 'Eren'],
  ['lastName', 'Duran'],
  ['age', 22],
  ['role', 'admin'] ],

现在,a 是一个包含子数组项(元组 - 值对)的数组,我们希望将其加入对象中。因此,将.reduce() 应用到a 对于这项工作非常方便;

a.reduce((o,t) => Object.assign(o,{[t[0]]:t[1]}),{})

我们的.reduce() 函数是接受初始值的类型,它是上述代码的最后一部分...,{})。这个最初为空的对象将被分配给它的回调的第一个参数o。然后像['firstName', 'Eren'] 这样的每个元组将在每一轮一个接一个地分配给回调的第二个参数t。它们将在Object.assign(o,{[t[0]]:t[1]}) 指令的帮助下累积在空对象中。它将采用o 的当前空值并将{firstname: "Eren"} 合并(加入)到它。箭头函数将返回Object.assign() 的输出作为新的o 值,以便在下一回合中使用。在下一回合中,o 现在是 {firstname: "Eren"}t["lastname", "Duran"] 如果我们替换我们现在拥有的值 Object.assign({firstname: "Eren"},{lastname: "Duran"}) 将返回 {firstname: "Eren", lastname: "Duran"} 并且这将作为我们的新 o 和等等……

所以我希望现在很清楚。

【讨论】:

  • @Nina Scholz 在评论中他提到“......或者如果没有递归解决方案......那么:如何不覆盖我的 obj......”
  • 这段代码完成了这项工作——但我不知道怎么做。 reduce 对我来说是一个黑匣子:我不理解什么以及如何工作。我什至可以在 Mozzilla 上读到 o 是累加器,t 是值——但你是如何得出这个解决方案的,你是如何提前知道构想它的——太棒了!
  • @tonycor nikolauos 所以你可能会感到困惑,因为这里的.reduce() 使用了一个空对象{} 作为初始值。请查看the second table in this link 以获取分步说明。我还将在我的答案中添加一个解释。
【解决方案2】:

不确定递归解决方案(我认为在这种特定情况下您不需要它,如果存在更深的嵌套,如果子数组中有许多子数组...主数组的子数组,您将需要一个)。

您当前的解决方案几乎可以正常工作,您只需要两个修复,在每次迭代时制作新对象,而不是在函数开始时(这就是您之前的值被覆盖的原因),以及一个用于推送创建的对象的最终数组。像这样的:

var array = [
    [
         ['firstName', 'Eren'], ['lastName', 'Duran'], ['age', 22], ['role', 'admin']
    ], 
    [
        ['firstName', 'Sallito'], ['lastName', 'Jordan'], ['age', 16], ['role', 'server']
    ]
];
function transformData(array) {
   
   final=[];
     for(var i = 0; i < array.length; i++){  
     var obj = {}; // create new object inside loop -> number of objects, number of arrays
       for(var j = 0; j < array[i].length; j++){
          for(var k = 0; k < array[i][j].length; k++){
                 if(k === 0){
                 var currentKey = array[i][j][k];
                 var currentValue = array[i][j][k + 1];
                     obj[currentKey] = currentValue;
                 }
                 
          }
      }
      final.push(obj); // push objects into final array
  }
  
     return final;
  }
  
  console.log(transformData(array));

这也是(恕我直言)简化版:

var array = [
    [
         ['firstName', 'Eren'], ['lastName', 'Duran'], ['age', 22], ['role', 'admin']
    ], 
    [
        ['firstName', 'Sallito'], ['lastName', 'Jordan'], ['age', 16], ['role', 'server']
    ]
];

function transform(data) {
output=[];
data.forEach(function(el) {
obj={};
for(j=0;j<el.length;j++) {
obj[el[j][0]]=el[j][1];
}
output.push(obj); 
});
return output;

}

console.log(transform(array));

附: @Redu 的答案是更多的 javascript-y,reduce 很棒,当然,这只是为了初学者(解释原始代码中的错误)。 ;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 2018-04-20
    • 2020-08-04
    • 2016-11-03
    相关资源
    最近更新 更多