繁体   English   中英

循环遍历嵌套数组并转换为对象

[英]Looping through nested arrays and converting to objects

我想将一组嵌套数组转换为一个对象数组,其中包含从嵌套数组中收集的信息:

前:

var employeeData = [
  [
    ['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson']
  ],
  [
    ['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director']
  ]
]

后:

[
  {firstName: 'Bob', lastName: 'Lob', age: 22, role: 'salesperson'},
  {firstName: 'Mary', lastName: 'Joe', age: 32, role: 'director'}
]

这是我为解决这个问题而编写的函数,但我不太清楚循环哪里出错了:

 var employeeData = [ [ ['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson'] ], [ ['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director'] ] ] function transformData(employeeData) { let newObject = {}; let newArr = []; for (var i = 0; i < employeeData.length; i++) { for (var x = 0; x < employeeData[i].length; x++) { for (var y = 0; y < employeeData[i][y].length; y++) { newObject[employeeData[i][y][0]] = employeeData[i][y][1]; } } newArr.push(newObject); newObject = {}; } return newArr; } console.log(transformData(employeeData));

提前致谢。

您的代码有什么问题:

第三个层次for循环被搞砸了。 它应该删除:

for (var y = 0; y < employeeData[i][x].length; y++) {
//                                  ^ by the way this should be x not y (not fixing the problem though)

因为第三级数组包含您需要同时使用的2个元素(作为键值), 所以应该删除它们的for循环

固定:

for (var i = 0; i < employeeData.length; i++) { 
    for (var x = 0; x < employeeData[i].length; x++) { 
        newObject[employeeData[i][x][0]] = employeeData[i][x][1];
    }
    newArr.push(newObject);
    newObject = {};
}

修复代码示例:

 var employeeData = [ [ ['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson'] ], [ ['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director'] ] ] function transformData(employeeData) { let newObject = {}; let newArr = []; for (var i = 0; i < employeeData.length; i++) { for (var x = 0; x < employeeData[i].length; x++) { newObject[employeeData[i][x][0]] = employeeData[i][x][1]; } newArr.push(newObject); newObject = {}; } return newArr; } console.log(transformData(employeeData)); 

替代方案:

您可以map employeeData数组map到一个新数组, reduce每个子数组reduce为如下对象:

var result = employeeData.map(function(sub) {
    return sub.reduce(function(obj, pair) {
        obj[ pair[0] ] = pair[1];
        return obj;
    }, {});
});

可以使用ES6的箭头功能将其缩短为:

let result = employeeData.map(sub => sub.reduce((obj, pair) => (obj[pair[0]] = pair[1], obj), {}));

例:

 let employeeData = [ [ ['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson'] ], [ ['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director'] ] ]; let result = employeeData.map(sub => sub.reduce((obj, pair) => (obj[pair[0]] = pair[1], obj), {})); console.log(result); 

如何修复代码

您只需要2个for循环:1。迭代数组2.迭代子数组并构造对象

 var employeeData = [[["firstName","Bob"],["lastName","Lob"],["age",22],["role","salesperson"]],[["firstName","Mary"],["lastName","Joe"],["age",32],["role","director"]]] function transformData(employeeData) { let newObject; const newArr = []; for (var i = 0; i < employeeData.length; i++) { newObject = {}; // init new object for (var x = 0; x < employeeData[i].length; x++) { newObject[employeeData[i][x][0]] = employeeData[i][x][1]; // iterate inner arrays and assign properties to object } newArr.push(newObject); } return newArr; } console.log(transformData(employeeData)); 

另一种选择是使用Array#map的组合来迭代外部数组,使用Array#reduce从内部数组构造一个对象:

 const employeeData = [[["firstName","Bob"],["lastName","Lob"],["age",22],["role","salesperson"]],[["firstName","Mary"],["lastName","Joe"],["age",32],["role","director"]]] const result = employeeData.map((arr) => arr.reduce((o, [key, value]) => (o[key] = value, o), {}) ); console.log(result); 

问题是你使用变量x和y

一方面,就是这条线

for (var y = 0; y < employeeData[i][y].length; y++)

也许你的意思是使用employeeData[i][x].length ,因为正如你在这里所说的那样,它会表现得非常奇怪。

但是,如果将其替换为x (在您的实现中从未使用过),您可以完全消除变量y

这是我对你的功能的建议编辑:

function transformData(employeeData) {
  let newObject = {}; 
  let newArr = []; 

  for (var i = 0; i < employeeData.length; i++) { 
    for (var x = 0; x < employeeData[i].length; x++) { 
      newObject[employeeData[i][x][0]] = employeeData[i][x][1];
    }   
    newArr.push(newObject);
    newObject = {}; 
  }
  return newArr;
}

运行这些更改的示例我得到了正确的输出:

[
  {
    firstName: 'Bob',
    lastName: 'Lob',
    age: 22,
    role: 'salesperson'
  },
  {
    firstName: 'Mary',
    lastName: 'Joe',
    age: 32,
    role: 'director'
  }
]

如果您正确使用索引,就可以使用for循环解决您遇到的问题。 如果你像我一样格式化数据,你会看到你的[i,x,y]索引有三个级别;

例如,对于employeeData [0]你应该得到:

[
    ['firstName', 'Bob'],
    ['lastName', 'Lob'],
    ['age', 22],
    ['role', 'salesperson']
  ]

那么对于employeeData [0] [0]你应该得到:

 ['firstName', 'Bob']

对于employeeData [0] [0] [0]你应该得到: 'firstName'

要访问'Bob',您需要employeeData [0] [0] [1],因为您知道此内部数组中只有两个元素,您不需要循环它。 正如@TallChuck所说,你问题的很大一部分源于忘记使用你的x索引。

 var employeeData = [ [ ['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson'] ], [ ['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director'] ] ] function transformData(employeeData) { let newObject = {}; let newArr = []; for (var i = 0; i < employeeData.length; i++) { for (var x = 0; x < employeeData[i].length; x++) { newObject[employeeData[i][x][0]] = employeeData[i][x][1]; } newArr.push(newObject); newObject = {}; } return newArr; } console.log(transformData(employeeData)); 

编辑


如果注意索引,也可以制作一些更复杂的解决方案。 假设您有以下数据:

var employeeData = [
  [
    ['firstName', 'Bob', 'weight', '80kg'],
    ['lastName', 'Lob'],
    ['age', 22],
    ['role', 'salesperson']
  ],
  [
    ['firstName', 'Mary', 'eye color', 'green'],
    ['lastName', 'Joe'],
    ['age', 32],
    ['role', 'director']
  ]
]

然后我给出的解决方案不会直接工作。 但是如果仔细观察,你会发现在某些数组中你的字段名称位于Y索引的0,2位。 这意味着您的字段名称位于一对位置,而字段值位于奇数位置。 所以你实际上可以通过y进行循环,然后检查Y索引是否可以被2整除。

if(y % 2 == 0 ..){}

只有当有一个伴随的奇数值时才这样做

if(y % 2 == 0 && employeeData[i][x][y+1]){..}

完整代码如下。

 var employeeData = [ [ ['firstName', 'Bob', 'weight', '80kg'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson'] ], [ ['firstName', 'Mary', 'eye color', 'green'], ['lastName', 'Joe'], ['age', 32], ['role', 'director'] ] ] function transformData(employeeData) { let newObject = {}; let newArr = []; for (var i = 0; i < employeeData.length; i++) { for (var x = 0; x < employeeData[i].length; x++) { for (var y = 0; y < employeeData[i][x].length; y++) { if(y % 2 == 0 && employeeData[i][x][y+1]){ newObject[employeeData[i][x][y]] = employeeData[i][x][y+1]; } } } newArr.push(newObject); newObject = {}; } return newArr; } console.log(transformData(employeeData)); 

您可能只想对外部数组中的每组值使用Map而不是Object

然后它是一个非常简单的new Map(data);转换new Map(data); 地图已添加到这些类型的数据集的规范中。

 var employeeData = [ [['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson']], [['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director']] ]; const res = employeeData.map(a => new Map(a)); for (const m of res) { console.log(m.get("firstName")); } 

但是如果你最终想要数组中的Object类型,那么你可以转换每个Map()

 var employeeData = [ [['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson']], [['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director']] ]; const res = employeeData.map(a => new Map(a)); for (const m of res) { console.log(m.get("firstName")); } const oRes = res.map(m => Object.assign({}, ...Array.from(m.entries()).map(([k,v]) => ({[k]:v})))); console.log(oRes); 

使用map和reduce更容易实现

var employeeData = [
  [
   ['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson']
   ],
  [
   ['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director']
  ]
  ]

var d = employeeData.map(
      x=>x.reduce((a,b)=>{a[b[0]]=b[1];return a;},{})
)


console.log(d)

这很容易在一行中完成。 Javascript 有一个专门用于此的功能。

 const employeeData = [ [ ['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson'] ], [ ['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director'] ] ] const res = employeeData.map(data => Object.fromEntries(data)) console.log(res)

干杯

其他人已经指出了如何使用map数组函数来简化你的任务,这些都是很好的解决方案(比计算循环要好得多),但它们并没有解决你实际问过的问题。

您的代码实际上工作得很好,您只是没有提取所有可用的数据。 你只有名字和姓氏。 通过再添加两行,您可以获得其余数据。 而且,第二个循环甚至不需要(它不会伤害你,但实际上并没有帮助,因为你从不在任何地方使用x计数器)。

 var employeeData = [ [ ['firstName', 'Bob'], ['lastName', 'Lob'], ['age', 22], ['role', 'salesperson'] ], [ ['firstName', 'Mary'], ['lastName', 'Joe'], ['age', 32], ['role', 'director'] ] ] function transformData(employeeData) { let newObject = {}; let newArr = []; for (var i = 0; i < employeeData.length; i++) { for (var y = 0; y < employeeData[i][y].length; y++) { newObject[employeeData[i][y][0]] = employeeData[i][y][1]; // Now you have to get the next two array elements as well: newObject[employeeData[i][y+1][0]] = employeeData[i][y+1][1]; newObject[employeeData[i][y+2][0]] = employeeData[i][y+2][1]; } newArr.push(newObject); newObject = {}; } return newArr; } console.log(transformData(employeeData)); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM