三维数组转换成对象数组

7

我在这个问题上卡了一段时间。

let employees = [
 [
  ['firstName', 'Joe'],
  ['lastName', 'Blow'],
  ['age', 42],
  ['role', 'clerk']
 ],
 [
  ['firstName', 'Mary'],
  ['lastName', 'Jenkins'],
  ['age', 36],
  ['role', 'manager']
 ]
]

产生:
[
    {firstName: 'Joe', lastName: 'Blow', age: 42, role: 'clerk'},
    {firstName: 'Mary', lastName: 'Jenkins', age: 36, role: 'manager'}
]

我该如何准确地进行转换?我已经尝试了三层嵌套的for循环、map/reduce和shift(),但我无法准确地完成转换。

6个回答

5

尝试这个解决方案。使用Array#map来迭代一级项。在map函数中,通过Array#forEach迭代嵌套数组项,并填充您的对象。然后从map返回该对象。

let employees = [
 [
  ['firstName', 'Joe'],
  ['lastName', 'Blow'],
  ['age', 42],
  ['role', 'clerk']
 ],
 [
  ['firstName', 'Mary'],
  ['lastName', 'Jenkins'],
  ['age', 36],
  ['role', 'manager']
 ]
];

const newEmp = employees.map(emp => {
   const obj = {};
   
   emp.forEach(([prop, value]) => obj[prop] = value);
   
   return obj;
});

console.log(newEmp);


哇,我从未想过要使用 [0] 或 [1],因为它们的属性可能是不可预测的。非常感谢。 - jhazelton1
1
你也可以将 forEach 函数更改为 ([key, value]) => obj[key] = value - Aadit M Shah

4
你可以使用 Array#map 循环遍历外/主数组。
然后,你可以使用 Array#reduce 将主数组中每个数组转换为对象。

let employees = [
    [
        ['firstName', 'Joe'],
        ['lastName', 'Blow'],
        ['age', 42],
        ['role', 'clerk']
    ],
    [
        ['firstName', 'Mary'],
        ['lastName', 'Jenkins'],
        ['age', 36],
        ['role', 'manager']
    ]
];

employees = employees.map(employee => employee.reduce((acc, item) => {
    acc[item[0]] = item[1];
    return acc;
}, {}));

console.log(employees);


你也可以将内部函数更改为(acc, [key, value]) => { acc[key] = value; return acc; } - Aadit M Shah
当我处理这个问题时,第一个索引返回的是'firstName', 'Joe',而其他的返回的是lastName: 'Blow'. - jhazelton1
@AaditMShah 感谢您的留言。 - Mohamed Abbas
@jhazelton1,对我来说它运行得很好。你尝试在StackOverflow上点击“运行代码片段”按钮了吗? - Mohamed Abbas
@MohamedAbbas 当我运行代码片段时,它在StackOverflow中可以工作,因此我的Atom文本编辑器中一定有错误。谢谢。 - jhazelton1
@jhazelton1 这不是关于你的编辑器,而是关于引擎。请检查您的浏览器控制台。 - Mohamed Abbas

3
这是我会做的事情:

const employees = [
    [
        ['firstName', 'Joe'],
        ['lastName', 'Blow'],
        ['age', 42],
        ['role', 'clerk']
    ],
    [
        ['firstName', 'Mary'],
        ['lastName', 'Jenkins'],
        ['age', 36],
        ['role', 'manager']
    ]
];

const entriesToObject = entries => {
    const object = {};
    for (const [key, value] of entries)
        object[key] = value;
    return object;
};

const result = employees.map(entriesToObject);

console.log(result);

请注意,result可以通过使用Object.entries将其转换回employees,代码如下:

const result = [
    {
        firstName: 'Joe',
        lastName: 'Blow',
        age: 42,
        role: 'clerk'
    },
    {
        firstName: 'Mary',
        lastName: 'Jenkins',
        age: 36,
        role: 'manager'
    }
];

const employees = result.map(Object.entries);

console.log(employees);

因此,entriesToObject函数非常有用,因为它是Object.entries反函数

2

这似乎可以工作:

let employees = [
    [
        ['firstName', 'Joe'],
        ['lastName', 'Blow'],
        ['age', 42],
        ['role', 'clerk']
    ],
    [
        ['firstName', 'Mary'],
        ['lastName', 'Jenkins'],
        ['age', 36],
        ['role', 'manager']
    ]
];

translated = []

for(let dataGroup of employees) {
    person = {};

    for(let dataPoint of dataGroup) {
        person[dataPoint[0]] = dataPoint[1]
    }

    translated.push(person);
}

console.log(translated);


1
你也可以将内部的 for 循环改为 for (const [key, value] of dataGroup) person[key] = value; - Aadit M Shah

2
你可以使用组合的方式。
  1. Array#map,用于完整的新对象和仅带有键/值对的对象,

  2. Object.assign,用于将单个/值对对象作为参数创建一个新对象,

  3. 展开语法 ...,用于将数组的每个元素作为参数,

  4. 解构赋值,用于从数组中获取键和值,

  5. 计算属性名,用于将动态键放入对象文字中。

employees.map(a => Object.assign(...a.map(([k, v]) => ({ [k]: v }))))
//        ^^^                         ^^^                              1 Array#map
//                 ^^^^^^^^^^^^^                                       2 Object.assign
//                               ^^^                                   3 spread syntax
//                                         ^^^^^^                      4 destructuring
//                                                       ^^^           5 computed prop

let employees = [[['firstName', 'Joe'], ['lastName', 'Blow'], ['age', 42], ['role', 'clerk']], [['firstName', 'Mary'], ['lastName', 'Jenkins'], ['age', 36], ['role', 'manager']]];
    result = employees.map(a => Object.assign(...a.map(([k, v]) => ({ [k]: v }))));
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


使用 Object.assign 和展开运算符组合起来真的非常聪明。 - Aadit M Shah

0

对于不同的方法,可以使用{{link1:Array#reduce}}和{{link2:Array#forEach}}函数进行操作

let employees = [
  [
    ['firstName', 'Joe'],
    ['lastName', 'Blow'],
    ['age', 42],
    ['role', 'clerk']
  ],
  [
    ['firstName', 'Mary'],
    ['lastName', 'Jenkins'],
    ['age', 36],
    ['role', 'manager']
  ]
]

var res = employees.reduce((a, b) => {
  var obj = {};
  b.forEach(function(i) {
    obj[i[0]] = i[1];
  })
  a.push(obj);
  return a;
}, [])

console.log(res)


为什么不直接使用 map 呢? - Aadit M Shah
已经有很多人使用了map函数,这就是为什么我添加了不同的方法。我的回答有什么问题吗?为什么要对我的回答进行负评?@AaditMShah - prasanth
1
在这个问题中,使用reduce而不是map会使问题变得更加复杂。话虽如此,如果您编辑您的答案并承认在这种情况下使用map更好,那么我愿意取消点赞。如果您不编辑答案,我无法取消点赞。 - Aadit M Shah
复杂的答案也是其中之一。这是一个学习平台,人们可以获得各种东西。我肯定不会编辑我的答案。我不是在乞求投票。 - prasanth
当然,那是你的权利。但请注意,即使我想要删除投票,我也无法这样做,因为我的投票已经被锁定了。唯一的方法是您编辑您的答案,我才能将其删除。 - Aadit M Shah
我已经编辑了我的回答。但对于你的方法来说不应该这样做。@AaditMShah - prasanth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接