[英]What is the best approach to clone objects properties when using map()?
I want to add a new property (contactDetails.countryName) and assign a value to a nested object stored in an array called users using the function map(). 我想添加一个新属性(contactDetails.countryName),并使用函数map()为存储在名为users的数组中的嵌套对象赋值。
I've recently learned that I should use the spread operator (...) and then create / assign the new property in order to avoid mutating my original array of objects so I've developed 2 different implementations for this but I'm not really confident I'm following the best practices to accomplish I want to regarding the semantic and performance. 我最近了解到我应该使用扩展运算符(...),然后创建/赋值新属性,以避免改变我原来的对象数组,所以我为此开发了2个不同的实现,但我不是我非常自信我正在遵循最佳实践来实现我想要的语义和性能。
What would be the best approach to accomplish what I want to do in your opinion? 在您看来,完成我想要做的最佳方法是什么?
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);
Here is an approach you can consider: 您可以考虑以下方法:
First of all I would Array.reduce the countries to a Map so you can get them via key
/ value
or in this case by countries.get(key)
and avoid filtering that array every time. 首先,我将Array.reduce国家/地区转换为Map,以便您可以通过
key
/ value
或在这种情况下通过countries.get(key)
获取它们,并避免每次都过滤该数组。
You can map through the users and for each one create a new object. 您可以通过用户进行映射,并为每个用户创建一个新对象。 In this case I call them
accounts
. 在这种情况下,我称他们为
accounts
。
You can also consider using Object.assign 您还可以考虑使用Object.assign
...
operator and Object.assign
are shallow clone approaches . ...
运营商和Object.assign
是浅克隆方法 。 They do not recursively clone the nested objects/children. JSON.stringify
and JSON.parse
etc. 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
Notice when we update the users[0].id
and users[0].contactDetails.phone
the accounts values did not update. 请注意,当我们更新
users[0].id
和users[0].contactDetails.phone
,帐户值未更新。
I normally use version 1, the spread operator twice. 我通常使用版本1,扩展运算符两次。 I also would consider checking out immer which allows you to do mutable updates on a cloned draft and handles merging it back for you.
我还会考虑检查immer ,它允许你对克隆的草稿进行可变更新并处理合并它。
const newUser = immer(user, draft => {
draft.contactDetails.countryName = countries.find(
c => c.id == user.contactDetails.country).countryName
)
})
Just edit the specific property you want and immer handles copying the rest of it. 只需编辑您想要的特定属性,immer处理复制其余属性。
Cloning and merging MapsSection Just like Arrays, Maps can be cloned: 克隆和合并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
I personally like to use Version 1, as it makes your code much less redundant and easier to read. 我个人喜欢使用版本1,因为它使您的代码更少冗余且更易于阅读。 It also passes all the properties of 'user' down to newUser.
它还将'user'的所有属性传递给newUser。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.