[英]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.