我想将项目从一个数组推送到另一个数组,但我只得到最后一个项目的重复项。有没有办法或更好的方法来解决这个问题?谢谢
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)
答案 0 :(得分:2)
如其他答案中所述,问题在于您每次迭代都在更改现有对象,而不是添加新对象。
我想补充一点,您也可以使用 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}`;
})
}, [])
可以在 MDN docs 中找到有关 reduce
函数的更多信息。
如果您想详细了解您的解决方案为何不起作用,请务必了解在 JS 中 primitive values
和 objects
之间的区别。
通过将包含对象的变量分配给另一个变量,您不是在分配新对象,而只是指向现有对象。这会导致您的对象之间发生耦合,它们指向同一个对象,如下所示:
var obj1 = {name: 'Sherlock Holmes', country: 'England'}
var obj2 = obj1;
obj2.country = 'US';
console.log(obj1.country) // US
console.log(obj2.country) // US
因此,当您想将一个对象分配给另一个变量时,您需要克隆其内容,但创建一个新对象,因此该变量将指向一个新对象而不是指向旧的。
有很多方法可以做到,但很少有简单的方法:
var obj1 = {name: 'Sherlock Holmes', country: 'England'}
var obj2 = { ...obj1 };
obj2.country = 'US';
console.log(obj1.country) // England
console.log(obj2.country) // US
JSON.stringify
和 JSON.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 的 {{ 1}} 函数。
答案 1 :(得分:1)
只需克隆 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)
答案 2 :(得分:1)
您的问题是每次都将相同的对象添加到列表中,num2
。 num2
本身不会在循环的每次迭代中发生变化。
这是你永远不会将 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)
答案 3 :(得分:1)
从原始数组创建新数组是一个相当简单的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)
答案 4 :(得分:0)
那是因为您在 em
循环的每次迭代中不断将同一个对象推送到 forEach
数组。
一个简单的方法是这样做:
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
变量并不意味着它持有的值是不可变的;我们只是将新元素推入数组 which is perfectly possible。