我想添加一个新属性(contactDetails.countryName),并使用map()函数将值分配给存储在称为用户的数组中的嵌套对象。
我最近了解到我应该使用散布运算符(...),然后创建/分配新属性,以避免变异对象的原始数组,因此我为此开发了2种不同的实现,但是我并没有真正的信心遵循最佳实践来实现我想要的语义和性能。
在您看来,实现我想做的最好的方法是什么?
const countries = [
{ id: 3, countryName : "UK" },
{ id: 4, countryName : "Spain" },
{ id: 6, countryName : "Germany"}
];
const users = [
{ id : 1,
name: "Douglas Camp",
dateOfBirth: "23-06-1984",
contactDetails:
{
country: 3,
phone: "7373724997"
}
},
{
id : 2,
name: "Martin Stein",
dateOfBirth: "19-08-1992",
contactDetails:
{
country: 6,
phone: "3334343434"
}
},
];
const usersData = users.map(user=> {
// Version 1 : using spreading operator twice
const newUser = {
...user,
contactDetails: {
...user.contactDetails,
countryName: countries.find(c=> c.id == user.contactDetails.country).countryName
}
};
return newUser;
});
// Version 2: copying the original object property and using spread operator only for cloning the nested object properties
const newUser = {
id: user.id,
name: user.name,
dateOfBirth: user.dateOfBirth,
contactDetails: {
...user.contactDetails,
countryName: countries.find(c=> c.id == user.contactDetails.country).countryName
}
};
console.log(users);
console.log(usersData);
答案 0 :(得分:1)
这是您可以考虑的一种方法:
首先,我将Array.reduce个国家Map},这样您就可以通过key
/ value
或在这种情况下通过{{1 }},并避免每次都过滤该数组。
您可以映射用户,并为每个用户创建一个新对象。在这种情况下,我称它们为countries.get(key)
。
您也可以考虑使用Object.assign
accounts
运算符和...
都是浅克隆方法。它们不会递归地克隆嵌套的对象/子级。为此,您可以使用Object.assign
和JSON.stringify
等。
JSON.parse
当我们更新let countries = [
{ id: 3, countryName : "UK" },
{ id: 4, countryName : "Spain" },
{ id: 6, countryName : "Germany"}
].reduce((r,{id, countryName}) => (r.set(id, countryName), r), new Map()) // reduce with Map
let users = [ { id : 1, name: "Douglas Camp", dateOfBirth: "23-06-1984", contactDetails: { country: 3, phone: "7373724997" } }, { id : 2, name: "Martin Stein", dateOfBirth: "19-08-1992", contactDetails: { country: 6, phone: "3334343434" } }, ];
let accounts = users.map(user => Object.assign({}, user, { // <-- map through
contactDetails: {
...user.contactDetails,
countryName: countries.get(user.contactDetails.country) // <-- get by key
}
}))
users[0].id = 2 // <-- modify users
users[0].contactDetails.phone = "00000"
console.log(users, accounts) // <-- no changes to accounts
和users[0].id
时,帐户值未更新。
答案 1 :(得分:0)
我通常使用版本1,即传播算子两次。我还考虑考虑使用immer,它允许您对克隆的草稿进行可变更新,并为您合并。
const newUser = immer(user, draft => {
draft.contactDetails.countryName = countries.find(
c => c.id == user.contactDetails.country).countryName
)
})
只需编辑所需的特定属性,然后沉浸式处理其余内容。
答案 2 :(得分:0)
克隆和合并MapsSection 就像数组一样,可以克隆地图:
var original = new Map([
[1, 'one']
]);
var clone = new Map(original);
console.log(clone.get(1)); // one
console.log(original === clone); // false. Useful for shallow comparison
答案 3 :(得分:0)
我个人喜欢使用版本1,因为它使您的代码少了很多冗余,而且更易于阅读。还将“用户”的所有属性传递给newUser。