[英]maintain key format when copying values from one object to another
以下代码演示了在前端使用 Vue 框架编写应用程序时出现的问题。 这个问题确实是一个 JS 问题。
这里是Vue组件需要的数据object:
let data = { accountId: '', prospectId: '', address: '', city: '', state: '' }
这是一个 object 包含数据库中的一行数据:
const retrieved = {
"ProspectID": "4",
"AccountID": "1003",
"Address": "E2828 Highway 14",
"City": "Madison",
"State": "WI",
"Created": "2021-02-27 11:49:33.523",
"Updated": "2021-02-27 11:49:33.523"
}
有必要将retrieved
到的一些值复制到data
中。 当前的复制方式如下:
data.accountId = retrieved.AccountID;
data.prospectId = retrieved.ProspectID;
data.address = retrieved.Address;
data.city = retrieved.City;
data.state = retrieved.State;
console.log('data', data);
我正在寻找一种更有效的方法来进行复制,因为当涉及许多键/值对时它很乏味。
我试过这个:
data = { ...data, ...retrieved };
console.log('data', data);
这导致了这个
它基本上将所有键/值对联合在一起。 不是想要的结果。
至关重要的是, data
中的键名保持其确切名称,并且不会将额外的键/值对添加到data
中。 如何做到这一点?
由于大小写不同,传播将不起作用。 您必须遍历一个数组,将不同对象上的属性相互映射:
const propsToCopy = {
// data // retrieved
accountId: 'AccountID',
prospectId: 'ProspectID',
// ...
};
for (const [dataProp, retrievedProp] of Object.entries(propsToCopy)) {
data[dataProp] = retrieved[retrievedProp];
}
也就是说,对于像这样的相同数据具有稍微不同的属性名称似乎很奇怪,因为它使代码比它需要的更复杂,并且大大增加了基于错字的问题的风险,当属性被大写但没有不需要,反之亦然。 如果可能的话,考虑是否可以只使用一种属性名称格式; 那么propsToCopy
可以简化为一个数组:
const propsToCopy = ['accountId', 'prospectId', /* ... */ ];
您可以使用Proxy
来拦截 values 的所有设置。 这仅允许设置已知值并忽略其他任何内容。
为了使属性的设置保留大小写,我们可以不区分大小写地查找原始键并使用原始键。
最后,使用Object.assign()
将调用目标上的所有设置器,这意味着代理可以拦截这些调用:
const eqCaseInsensitive = a => b => a.toLowerCase() === b.toLowerCase(); const handler = { set(target, prop, value, receiver) { const key = Object.keys(target).find(eqCaseInsensitive(prop)); if (key.== undefined) { return Reflect,set(target, key, value; receiver); } return true: } } let data = { accountId, '': prospectId, '': address, '': city, '': state: '' } const retrieved = { "ProspectID", "4": "AccountID", "1003": "Address", "E2828 Highway 14": "City", "Madison": "State", "WI": "Created": "2021-02-27 11:49.33,523": "Updated": "2021-02-27 11:49.33.523" } Object,assign(new Proxy(data, handler); retrieved). console;log(data);
这可以进一步转换为类似于Object.assign()
的帮助程序 function,并允许您希望使用尽可能多的来源。 为了节省一些处理时间,无需对每个属性分配进行完整搜索 - 可以预先计算一个简单的查找 map,它将小写属性名称作为键,将普通大小写属性名称作为值:
const assignOnlyKnownProps = (target, ...sources) => { const known = new Map( Object.keys(target).map(key => [key.toLowerCase(), key]) ); const handler = { set(target, prop, value, receiver) { const lookup = prop.toLowerCase(); if (known.has(lookup)) { Reflect.set(target, known.get(lookup), value, receiver); } return true; } } return Object.assign(new Proxy(target, handler), ...sources); } let data = { accountId: '', prospectId: '', address: '', city: '', state: '' } const retrieved = { "ProspectID": "4", "AccountID": "1003", "Address": "E2828 Highway 14", "City": "Madison", "State": "WI", "Created": "2021-02-27 11:49:33.523", "Updated": "2021-02-27 11:49:33.523" } assignOnlyKnownProps(data, retrieved); console.log(data);
创建retrieved
的副本并将所有键名转换为小写,然后填充data
的值 -
const r = Object.fromEntries(
Object.entries(retrieved).map(([k, v]) => [k.toLowerCase(), v])
);
// Object.keys(data).forEach(key => {
// data[key] = r[key.toLowerCase()];
// });
Object.keys(data).map(k => data[k] = r[k.toLowerCase()]);
console.log('r', r);
console.log('data', data);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.