JavaScript中将多个数组合并为对象数组

6

假设我有三个数组,分别描述一些人的姓名,读的书籍数量以及这些人的[在名字中]厉害程度:

let names = ["Mary", "Joe", "Kenan"];
let numberOfBooks = [2, 1, 4];
let awesomenessLevel = ["pretty cool", "meh", "super-reader"];

我正在尝试使用.reduce()将它们组合在一起,创建一个包含每个数组中相关索引的对象数组,但是我失败了:

    let people = [
    {
       name: "Mary",
       noOfBooks: 2,
       awesomeness: "pretty cool"
    },
    {
       name: "Joe",
       noOfBooks: 1,
       awesomeness: "meh"
    },
    {
       name: "Kenan",
       noOfBooks: 4,
       awesomeness: "super-reader"
    }
  ]

我也使用reduce方法做到了:

let arrFinal = [];

 names.reduce(function(all, item, index) {
  arrFinal.push({
    name: item,
    noOfBooks: numberOfBooks[index],
    awesomeness: awesomenessLevel[index]
  })
}, []);

你用reduce的方式并没有发挥其优点:注意回调函数没有返回值,all累加器没有使用,这些是选择reduce的典型特征。你可以将那段代码中的reduce替换为forEach(并根据需要调整参数-去掉all),结果是一样的。 - trincot
你说得完全正确,我只是拼命地添加它们:s。我想我需要更多地学习如何正确使用reduce。 - vzR
3个回答

7
您可以使用map来实现,例如:
let result = names.map( (v, i) => ({
    name: names[i], 
    noOfBooks: numberOfBooks[i],
    awesomenessLevel: awesomenessLevel[i]
}));

let names = ["Mary", "Joe", "Kenan"];
let numberOfBooks = [2, 1, 4];
let awesomenessLevel = ["pretty cool", "meh", "super-reader"];

let result = names.map( (v, i) => ({
    name: names[i], 
    noOfBooks: numberOfBooks[i],
    awesomenessLevel: awesomenessLevel[i]
}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

map在这种情况下比reduce更好,因为你在names数组中(或其他两个数组之一)拥有的元素数量与你需要在输出中拥有的元素数量相同。在这种情况下,使用map更加自然。


你说得对,我认为使用reduce需要在之前定义一个数组,而在这里你只需加载结果。非常感谢。 - vzR
不客气 ;-). 另外,我在你的问题评论中也提到了一些关于“reduce”的想法。 - trincot

5
使用map方法创建输入数组和输出数组之间的一对一映射。
let people = names.map(function (e, i) {
    return {name:e, noOfBooks:numberOfBooks[i],awesomeness: awesomenessLevel[i]};
});

let names = ["Mary", "Joe", "Kenan"];
let numberOfBooks = [2, 1, 4];
let awesomenessLevel = ["pretty cool", "meh", "super-reader"];

let people = names.map(function (e, i) {
    return {name:e, noOfBooks:numberOfBooks[i],awesomeness: awesomenessLevel[i]};
});


console.log(people);


另一个有用的信息:在代码片段中,可以使用console.log代替alert,这样您甚至不需要执行JSON.stringify,因为StackOverflow会为您执行。 :-) - trincot

1
你可以使用动态方法,将所有数组合并为一个对象,并使用键名作为结果对象在数组中的属性名称。

let names = ["Mary", "Joe", "Kenan"],
    numberOfBooks = [2, 1, 4],
    awesomenessLevel = ["pretty cool", "meh", "super-reader"],
    object = { name: names, noOfBooks: numberOfBooks, awesomeness: awesomenessLevel },
    result = Object.keys(object).reduce((r, k) =>
        (object[k].forEach((a, i) =>
            (r[i] = r[i] || {})[k] = a), r), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


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