将对象从一个阵列推送到另一个阵列



我想把项目从一个数组推送到另一个数组,但我只得到了最后一个项目的重复项。有没有更好的方法来解决这个问题?感谢

let nums = [{id:1, first_name: "sade", last_name: "Smith"}, {id:2, first_name: "Jon", last_name: "Doe"}];
let em = [];
let num2 = {id:null, name: ""}
nums.forEach(e => {
num2.id = e.id;
num2.name = `${e.first_name} ${e.last_name}`;
em.push(num2)
});
console.log(em)

正如其他答案中提到的,问题是每次迭代都要更改现有对象,而不是添加新对象。

我想补充一点,你也可以使用reduce(我个人更喜欢这种语法,它有点短(:

let nums = [{id:1, first_name: "sade", last_name: "Smith"}, {id:2, first_name: "Jon", last_name: "Doe"}];
let em = [];
let num2 = {id:null, name: ""}
em = nums.reduce((accumulator, item) => {
accumulator.push({
id: item.id,
name: `${item.first_name} ${item.last_name}`;
})
}, [])

有关reduce函数的更多信息,请参阅MDN文档。


为什么它会这样工作

如果您想了解更多关于解决方案不起作用的原因,那么了解JS中primitive valuesobjects之间的区别是很重要的。

通过将包含对象的变量指定给另一个变量,您不是在指定新对象,而是仅指向现有对象。这会导致对象之间的耦合,它们指向同一个对象,如图所示:

var obj1 = {name: 'Sherlock Holmes', country: 'England'}
var obj2 = obj1;
obj2.country = 'US';
console.log(obj1.country) // US
console.log(obj2.country) // US

因此,当您想将一个对象分配给另一个变量时,您需要克隆其内容,但要创建一个新对象,因此该变量将指向一个新对象,而不是旧对象。

有很多方法可以做到这一点,但很少有简单的方法:

  1. 使用如下排列运算符:

var obj1 = {name: 'Sherlock Holmes', country: 'England'}
var obj2 = { ...obj1 };
obj2.country = 'US';
console.log(obj1.country) // England
console.log(obj2.country) // US

  1. 使用JSON.stringifyJSON.parse进行字符串化然后进行解析

var obj1 = {name: 'Sherlock Holmes', country: 'England'}
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.country = 'US';
console.log(obj1.country) // US
console.log(obj2.country) // US

有更多的方法,而且这些方法之间的区别是,如果您的对象也有嵌套的对象,复制可能不会正确进行,此时最好使用一个为您进行克隆的函数,如lodash的deepClone函数。

只需克隆num2并推送克隆的对象。

let nums = [{id:1, first_name: "sade", last_name: "Smith"}, {id:2, first_name: "Jon", last_name: "Doe"}];
let em = [];
let num2 = {id:null, name: ""}
nums.forEach(e => {
const cloned = {...num2};
cloned.id = e.id;
cloned.name = `${e.first_name} ${e.last_name}`;
em.push(cloned)
});
console.log(em)

您的问题是,每次都要将相同的对象添加到列表num2中。CCD_ 9本身在循环的每次迭代中都没有改变。

这是一种效果,因为你从来没有将num2重新分配给任何新的东西,而且列表nums正在跟踪指向对象的指针列表,这意味着它实际上并没有每次都将num2复制到自己中,它只是将num2的指针放进去。

您应该1(克隆它,或者2(创建一个新对象,然后将其推送到列表中。

let nums = [{id:1, first_name: "sade", last_name: "Smith"}, {id:2, first_name: "Jon", last_name: "Doe"}];
let em = [];
let num2 = {id:null, name: ""}
nums.forEach(e => {
let temp_num = {...num2};
temp_num.id = e.id;
temp_num.name = `${e.first_name} ${e.last_name}`;
em.push(temp_num)
});
console.log(em)

从原始创建新数组是一个相当简单的map()操作

let nums = [{id:1, first_name: "sade", last_name: "Smith"}, {id:2, first_name: "Jon", last_name: "Doe"}];
let res = nums.map(({id, first_name:fn, last_name:ln}) => ({id, name: `${fn} ${ln}`}));
console.log(res)

这是因为在forEach循环的每次迭代中都会将同一个对象推送到em数组。

一个简单的方法是这样做:

const nums = [{id:1, first_name: "sade", last_name: "Smith"}, {id:2, first_name: "Jon", last_name: "Doe"}];
const em = [];
nums.forEach(e => {
em.push({id: e.id, name: `${e.first_name} ${e.last_name}`});
});
console.log(em);

您也可以在阵列上使用map功能:

const nums = [{id:1, first_name: "sade", last_name: "Smith"}, {id:2, first_name: "Jon", last_name: "Doe"}];
const em = nums.map((item) => ({id: item.id, name: `${item.first_name} ${item.last_name}`}));
console.log(em);

从本质上讲,我们正在创建一个新对象,并在循环和过程中的每次迭代中将其推送到em数组中,从而消除了对您声明的num2对象的需要。

此外,em变量可以被设为const,因为使用const变量并不意味着它所保持的值是不可变的;我们只是简单地将新元素推入数组,这是完全可能的。

最新更新