javascript - 修改 Javascript 对象内的值
问题描述
如果对象,我有以下数组:
[{id: 0
name: "Weight"
options: [
"250gr","500gr"],
position: 0
variation: true
visible: true},
{id: 0
name: "Roast"
options: ["Light", "Medium, "Dark],
position: 0
variation: true
visible: true},
{id: 0
name: "Packaging"
options: [
"Tin","Card"],
position: 0
variation: true
visible: true}
]
然后我详细说明以下内容:
[{id: 0, name: "Weight", option: "250gr"},
{id: 0, name: "Roast", option: "Medium"},
{id: 0, name: "Packaging", option: "Card"},
{id: 0, name: "Weight", option: "250gr"},
{id: 0, name: "Roast", option: "Light"},
{id: 0, name: "Packaging", option: "Card"}
]
是否可以根据第二组选项更改第一个的“选项”数组的值?我需要获得类似的东西:
[{id: 0
name: "Weight"
options: [
"250gr"],
position: 0
variation: true
visible: true},
{id: 0
name: "Roast"
options: ["Light", "Medium"],
position: 0
variation: true
visible: true},
{id: 0
name: "Packaging"
options: [
"Card"],
position: 0
variation: true
visible: true}
]
解决方案
tl;dr 将第二个options
数组转换为 Object 或 Map 以进行查找
在我看来,效率主要有两种形式:
- 开发人员的效率(维护)
- 代码效率(性能/速度)
通常,您想从 #1 开始,但有时您对 #2 的了解决定了您的整体方法(正如您将在我的示例中看到的那样)。
维护:对于未来的开发人员(可能是您)来说,阅读和理解什么最简单?此外,什么最容易扩展/更改和重用?这个话题有很多,它确实将初级开发人员与高级开发人员区分开来。一种更具声明性的方法通常很适合这里。这就是为什么我会推荐Array
像Array.map()
和/或这样的函数Array.reduce()
而不是for
循环。此外,这些有助于我的其他建议:不变性,或者至少将数据视为不可变。但是,这通常涉及克隆数据,这可能会在一定程度上降低性能。(注意:Spread 语法似乎在克隆数组时最快)
对于性能:我知道进行这样的搜索的最快方法之一是针对哈希图进行键查找(在 JS 中,anObject
或 aMap
可以解决问题)。所以,我会从那里开始。如果你的第二个options
数组已经是一个Object
,而不是一个,那将是理想的Array
,但我们至少可以改变你所拥有的。如果您愿意,您可以通过稍后更改数据(并删除转换代码)来进一步简化逻辑。
以下方法应在一定程度上满足这两种效率。这是我将所有这些放在一起的最佳示例,使用Object
:
const options = [
{ id: 0, name: "Weight", position: 0, variation: true, visible: true, options: ["250gr","500gr"] },
{ id: 0, name: "Roast", position: 0, variation: true, visible: true, options: ["Light", "Medium", "Dark"] },
{ id: 0, name: "Packaging", position: 0, variation: true, visible: true, options: ["Tin","Card"] },
];
const options2 = [
{ id: 0, name: "Weight", option: "250gr" },
{ id: 0, name: "Roast", option: "Medium" },
{ id: 0, name: "Packaging", option: "Card" },
{ id: 0, name: "Weight", option: "250gr" }, // Duplicate
{ id: 0, name: "Roast", option: "Light" },
{ id: 0, name: "Packaging", option: "Card" }, // Duplicate
];
// Transform options2 (Create an Object for hash lookup)
const options2Dictionary = options2.reduce((obj, o) => {
const arr = obj[o.name] ?? [];
if (!arr.includes(o.option)) arr.push(o.option); // ignore duplicates
obj[o.name] = arr;
return obj;
}, {});
// "Replace" (I'm copying values into new objects, instead of modifying)
const updatedOptions = options.map(o => ({
...o,
options: [...(options2Dictionary[o.name] ?? [])], // override "options" (clone array)
}));
console.log(updatedOptions);
同样的事情,使用Map
:
const options = [
{ id: 0, name: "Weight", position: 0, variation: true, visible: true, options: ["250gr","500gr"] },
{ id: 0, name: "Roast", position: 0, variation: true, visible: true, options: ["Light", "Medium", "Dark"] },
{ id: 0, name: "Packaging", position: 0, variation: true, visible: true, options: ["Tin","Card"] },
];
const options2 = [
{ id: 0, name: "Weight", option: "250gr" },
{ id: 0, name: "Roast", option: "Medium" },
{ id: 0, name: "Packaging", option: "Card" },
{ id: 0, name: "Weight", option: "250gr" }, // Duplicate
{ id: 0, name: "Roast", option: "Light" },
{ id: 0, name: "Packaging", option: "Card" }, // Duplicate
];
// Transform options2 (Create a Map for hash lookup)
const options2Dictionary = options2.reduce((map, o) => {
const arr = map.has(o.name) ? map.get(o.name): [];
if (!arr.includes(o.option)) arr.push(o.option); // ignore duplicates
map.set(o.name, arr);
return map;
}, new Map());
// "Replace" (I'm copying values into new objects, instead of modifying)
const updatedOptions = options.map(o => ({
...o,
options: [...(options2Dictionary.get(o.name) ?? [])], // override "options" (clone array)
}));
console.log(updatedOptions);
最后,如果您的数据已经是Object
:
const options = [
{ id: 0, name: "Weight", position: 0, variation: true, visible: true, options: ["250gr","500gr"] },
{ id: 0, name: "Roast", position: 0, variation: true, visible: true, options: ["Light", "Medium", "Dark"] },
{ id: 0, name: "Packaging", position: 0, variation: true, visible: true, options: ["Tin","Card"] },
];
const options2 = {
"Weight": [ "250gr" ],
"Roast": [ "Medium", "Light" ],
"Packaging": [ "Card" ],
};
// "Replace" (I'm copying values into new objects, instead of modifying)
const updatedOptions = options.map(o => ({
...o,
options: [...(options2[o.name] ?? [])], // override "options" (clone array)
}));
console.log(updatedOptions);
推荐阅读
- python - scipy.stats 对 iqr 的计算是否错误?
- angular - 获取组件中的路由参数
- javascript - 在这种情况下如何减少工作?
- javascript - 如何将输入值传递给其他函数
- vba - Excel VBA - 在空白单元格上自动创建超链接
- javascript - onClick 功能未在选择菜单中创建选项
- linux - Systemd 的 StartLimitIntervalSec 和 StartLimitBurst 从不工作
- .net - RDLC 表达式和数据集
- apache - 在 solaris 上通过 cgid 执行 perl 在 64 位下失败,但在 32 位下工作
- r - 使用 normalize.quantiles 时保留行名和列名