繁体   English   中英

将值从一个 object 复制到另一个时保持密钥格式

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM