在普通JS中重新对象的数组数组

时间:2017-01-21 20:42:40

标签: javascript arrays object recursion

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

{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方法。我真的很想学习递归。谢谢!

2 个答案:

答案 0 :(得分:0)

使用纯JS,您可以执行以下操作;

&#13;
&#13;
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);
&#13;
&#13;
&#13;

说明:我们在主阵列上应用.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等返回......

所以我希望现在很清楚。

答案 1 :(得分:0)

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

您当前的解决方案几乎没有问题,您只需要两次修复,在每次迭代时创建新对象,而不是在函数的开头(这就是为什么先前的值被覆盖),以及一个最终的数组到推送创建的对象。像这样:

&#13;
&#13;
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));
&#13;
&#13;
&#13;

这是(imho)简化版本,它也完成了这项工作:

&#13;
&#13;
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));
&#13;
&#13;
&#13;

P.S。 @Redu的答案更多是javascript-y,而reduce是很好的,当然,这只适用于初学者(解释原始代码中的错误)。 ;)