首页 > 解决方案 > 修改 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}
    ]

标签: javascriptarrays

解决方案


tl;dr 将第二个options数组转换为 Object 或 Map 以进行查找

在我看来,效率主要有两种形式:

  1. 开发人员的效率(维护)
  2. 代码效率(性能/速度)

通常,您想从 #1 开始,但有时您对 #2 的了解决定了您的整体方法(正如您将在我的示例中看到的那样)。

维护:对于未来的开发人员(可能是您)来说,阅读和理解什么最简单?此外,什么最容易扩展/更改和重用?这个话题有很多,它确实将初级开发人员与高级开发人员区分开来。一种更具声明性的方法通常很适合这里。这就是为什么我会推荐ArrayArray.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);


推荐阅读