在JavaScript中,将一个对象数组的值使用另一个对象数组的值进行替换

3

我有一个主数组:

 const purchaseData = [
  {
    product_id: "product_id_1",
    localized_title: "Product Title 1",
    ... other attributes
  },
  {
    product_id: "product_id_2",
    localized_title: "Product Title 2",
    ... other attributes
  },

我希望用一个数组替换localized_title,该数组包含某些产品ID的更新后的localized_title。

例如:

updatedData = [
  {
    product_id: "product_id_1",
    localized_title: "Updated Product Title 1",
    ...other random attributes // different from the attributes in the objects of purchaseData
  },
];

在这种情况下,purchaseData的第一个子元素只应更新其localized_title。是否有一种优雅的方法可以在不使用for循环和更改数据的情况下完成此操作?我尝试了许多方法,但似乎代码行数太多(不够简洁)。
这是我尝试过的内容:
const updatedData = purchaseData.map(obj => {
    const foundObject = originalProducts.find(
      o => o.product_id === obj.product_id,
    );
    const localized_title = foundObject && foundObject.localized_title
    if (localized_title) {
        return {...obj, localized_title}
    }
    return obj;
  });

1
也许你可以尝试使用 map()reduce() - norbitrial
3
你到底尝试了什么?其中有什么“不干净”的地方,这实际上引起了什么问题? - jonrsharpe
3
优雅在于看者的眼中。作为一名整天审查代码的人,我可以告诉你,我更愿意看到“过多”的代码行数,而不是过少但“聪明”的代码行数。 - Heretic Monkey
1
我更新了问题,包括我尝试过的内容。我不需要合并,而是需要替换一些值,因为这两个数组包含具有不同属性的对象。 - Bassem
1
我最担心的是其他开发人员阅读这段代码,我觉得它太复杂了 :/ - Bassem
显示剩余2条评论
2个回答

3
我会使用 Map 来简化获取对象(这也使代码为 O(n)):
  const productById = new Map(products.map(it => ([it.product_id, it])));

  const updated = purchases.map(purchase => {
    const product = productById.get(purchase.product_id);

    if (product && product.localized_title) {
      return { ...purchase, localized_title: product.localized_title, };
    }

    return purchase;
 });

1
另外,你的逻辑并不完全等价。你的 if 语句需要变成 if (product && product.localized_title)。这就是为什么我将中间表达式存储到一个 const 中,并使用了简写属性符号。 - Patrick Roberts
@patrick 确实,我不太确定是否需要这种行为。我仍然更喜欢 if(product && ...),因为它清楚地表明了意图。 - Jonas Wilms
1
我同意@PatrickRoberts提到的逻辑if (product && product.localized_title) - Bassem
@skoltz 如果这是你的意图,那么...另外,我拒绝了你的编辑,因为我认为删除“data”可以提高可读性... - Jonas Wilms
@ Skoltz 切记,如果“localized_title”在新对象中为空字符串,则将返回旧对象,因为“”为 false-y。 - Patrick Roberts

2

使用Map优化您的查找,将foundObject的搜索时间从O(n)降低到O(1),这将是值得的。此外,您可以将两个return语句合并为一个:

const originalProductsMap = new Map(
  originalProducts.map(o => [o.product_id, o])
);

const updatedData = purchaseData.map(oldData => {
  const newData = originalProductsMap.get(oldData.product_id);
  const localized_title = newData && newData.localized_title;

  return localized_title
    ? { ...oldData, localized_title }
    : oldData;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接