Javascript 将值从一个对象复制到另一个对象时保持键格式

Javascript 将值从一个对象复制到另一个对象时保持键格式,javascript,Javascript,下面的代码演示了在使用Vue框架为前端编写应用程序时出现的问题。不过,这确实是一个JS问题 以下是Vue组件所需的数据对象: let data = { accountId: '', prospectId: '', address: '', city: '', state: '' } 这是一个包含数据库中一行数据的对象: const retrieved = { "ProspectID": "4", "AccountID&q

下面的代码演示了在使用Vue框架为前端编写应用程序时出现的问题。不过,这确实是一个JS问题

以下是Vue组件所需的数据对象:

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"
}
有必要将检索到的
中的一些值复制到
数据中。当前的复制方式如下所示:

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);
这就导致了

基本上将所有键/值对合并在一起。不是预期的结果


数据
中的键名必须保留其确切名称,并且不能向
数据
添加额外的键/值对。如何实现这一点?

由于资本化不同,差价将不起作用。您必须迭代将不同对象上的属性映射到彼此的数组:

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', /* ... */ ];

由于资本化程度不同,利差就不起作用了。您必须迭代将不同对象上的属性映射到彼此的数组:

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', /* ... */ ];

创建已检索的
的副本
并将所有键名转换为小写,然后填充
数据的值
有效-

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);

创建检索到的
的副本
并将所有键名转换为小写,然后填充
数据的值
有效-

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);

您可以按顺序使用。这只允许设置已知值,而忽略任何其他内容

要使属性的设置保留大小写,我们只需不敏感地查找原始密钥大小写并使用原始密钥大小写即可

最后,使用将调用目标上的所有setter,这意味着代理可以拦截这些调用:

const eqCaseInsensitive=a=>b=>
a、 toLowerCase()==b.toLowerCase();
常量处理程序={
设定(目标、道具、价值、接受者){
常量键=对象键(目标)
.find(eqcase不敏感(prop));
如果(键!==未定义){
返回Reflect.set(目标、键、值、接收者);
}
返回true;
}
}
let data={accountId:'',prospectId:'',地址:'',城市:'',州:'}
检索到的常量={
“浏览ID”:“4”,
“帐户ID”:“1003”,
“地址”:“E2828 14号公路”,
“城市”:“麦迪逊”,
“州”:“WI”,
“已创建”:“2021-02-27 11:49:33.523”,
“更新”:“2021-02-27 11:49:33.523”
}
分配(新代理(数据、处理程序),已检索);
控制台日志(数据)您可以按顺序使用。这只允许设置已知值,而忽略任何其他内容

要使属性的设置保留大小写,我们只需不敏感地查找原始密钥大小写并使用原始密钥大小写即可

最后,使用将调用目标上的所有setter,这意味着代理可以拦截这些调用:

const eqCaseInsensitive=a=>b=>
a、 toLowerCase()==b.toLowerCase();
常量处理程序={
设定(目标、道具、价值、接受者){
常量键=对象键(目标)
.find(eqcase不敏感(prop));
如果(键!==未定义){
返回Reflect.set(目标、键、值、接收者);
}
返回true;
}
}
let data={accountId:'',prospectId:'',地址:'',城市:'',州:'}
检索到的常量={
“浏览ID”:“4”,
“帐户ID”:“1003”,
“地址”:“E2828 14号公路”,
“城市”:“麦迪逊”,
“州”:“WI”,
“已创建”:“2021-02-27 11:49:33.523”,
“更新”:“2021-02-27 11:49:33.523”
}
分配(新代理(数据、处理程序),已检索);
控制台日志(数据)