【问题标题】:Reducing array of objects based on object's inner array根据对象的内部数组减少对象数组
【发布时间】:2021-09-01 08:52:10
【问题描述】:

我有一个这样的数据集:

[
  {
    id: 'abc',
    productType: "Nappies"
    variants: ['3 Pack of Nappies', 'small']
  },
  {
    id: 'abc',
    productType: "Nappies"
    variants: ['6 Pack of Nappies', 'small']
  },
  {
    id: 'abc',
    productType: "Nappies"
    variants: ['12 Pack of Nappies', 'small']
  },
  {
    id: 'abc',
    productType: "Nappies"
    variants: ['3 Pack of Nappies', 'medium']
  },
  {
    id: 'abc',
    productType: "Nappies"
    variants: ['6 Pack of Nappies', 'medium']
  },
  {
    id: 'abc',
    productType: "Nappies"
    variants: ['12 Pack of Nappies', 'medium']
  },
  {
    id: 'def',
    productType: "Wipes"
    variants: ['3 Pack of Wipes']
  },
  {
    id: 'def',
    productType: "Wipes"
    variants: ['6 Pack of Wipes']
  },
  {
    id: 'def',
    productType: "Wipes"
    variants: ['12 Pack of Wipes']
  },
]

如您所见,每个产品 ID 在所有变体中都重复出现。我需要减少数据,因此每个产品只有 1 个版本带有“X 包尿布”,例如:

想要的结果:

[
  {
    id: 'abc',
    productType: "Nappies"
    variants: ['3 Pack of Nappies', 'small']
  },
  {
    id: 'abc',
    productType: "Nappies"
    variants: ['6 Pack of Nappies', 'small']
  },
  {
    id: 'abc',
    productType: "Nappies"
    variants: ['12 Pack of Nappies', 'small']
  },
  {
    id: 'def',
    productType: "Wipes"
    variants: ['3 Pack of Wipes']
  },
  {
    id: 'def',
    productType: "Wipes"
    variants: ['6 Pack of Wipes']
  },
  {
    id: 'def',
    productType: "Wipes"
    variants: ['12 Pack of Wipes']
  },
]

每个中的次要变体(大小,例如“小”/“中”)并不重要。我尝试运行一个 reduce 函数,该函数运行一个过滤器,如果 reduce 对象的“variants”属性包含任何活动对象的“variant”属性但它返回所有内容,则返回 true。

      const RemoveDuplicates = (array) => {
        return array.reduce((arr, item) => {
          const removed = arr.filter((obj) => {
            return obj.selectedOptions.some((i) =>
              item.selectedOptions.includes(i)
            )
          })
          return [...removed, item]
        }, [])
      }

【问题讨论】:

  • 从您的输出示例中不清楚您在问什么。你确定你的输出有代表性吗?
  • 从您的预期输出看来,您只想按variants 过滤重复项,但我觉得您实际上想按variant 分组并收集ids?

标签: javascript arrays ecmascript-6


【解决方案1】:

您所要做的就是从accumulator 中找到符合以下条件的匹配项

相同的id、相同的productType 和相同的variants[0]

逻辑

  • 使用Array.reduce 循环遍历数组。
  • 第一个参数acc是累加器,里面保存着累加的列表。下一个参数curr 是循环时保存数组每个节点的当前值。如果满足要求,您要做的就是将当前值推送到累加器。
  • 要检查要求,您必须检查acc 中的每个curr 值。如果accumulator 中有一个节点,每个curr 具有相同的idproductTypevariants[0],您称之为版本。如果累加器已经有一个匹配组合的节点,不要将当前值推送到accumulator

const input = [
  { id: 'abc', productType: "Nappies", variants: ['3 Pack of Nappies', 'small'] },
  { id: 'abc', productType: "Nappies", variants: ['6 Pack of Nappies', 'small'] },
  { id: 'abc', productType: "Nappies", variants: ['12 Pack of Nappies', 'small'] },
  { id: 'abc', productType: "Nappies", variants: ['3 Pack of Nappies', 'medium'] },
  { id: 'abc', productType: "Nappies", variants: ['6 Pack of Nappies', 'medium'] },
  { id: 'abc', productType: "Nappies", variants: ['12 Pack of Nappies', 'medium'] },
  { id: 'def', productType: "Wipes", variants: ['3 Pack of Wipes'] },
  { id: 'def', productType: "Wipes", variants: ['6 Pack of Wipes'] },
  { id: 'def', productType: "Wipes", variants: ['12 Pack of Wipes'] },
];

const output = input.reduce((acc, curr) => {
  const node = acc.find((item) =>
    item.id === curr.id &&
    item.productType === curr.productType &&
    item.variants[0] === curr.variants[0]);
    if(!node) {
      acc.push(curr)
    }
  return acc;
}, []);

console.log(output);

【讨论】:

  • 这很有帮助,谢谢@nitheesh!我没有完全掌握减速器,但这很简单,很高兴你使用了 ES6。
  • @MichaelPrecel 我已经用减速器逻辑更新了答案,请检查一下。如果这是您正在寻找的,请批准答案。很高兴也能获得支持。
【解决方案2】:

您可以使用复合键作为标准 group-by 执行此操作,但不是累积,而是使用该键作为重复项检查。

const input = [  { id: 'abc', productType: "Nappies", variants: ['3 Pack of Nappies', 'small'] },  { id: 'abc', productType: "Nappies", variants: ['6 Pack of Nappies', 'small'] },  { id: 'abc', productType: "Nappies", variants: ['12 Pack of Nappies', 'small'] },  { id: 'abc', productType: "Nappies", variants: ['3 Pack of Nappies', 'medium'] },  { id: 'abc', productType: "Nappies", variants: ['6 Pack of Nappies', 'medium'] },  { id: 'abc', productType: "Nappies", variants: ['12 Pack of Nappies', 'medium'] },  { id: 'def', productType: "Wipes", variants: ['3 Pack of Wipes'] },  { id: 'def', productType: "Wipes", variants: ['6 Pack of Wipes'] },  { id: 'def', productType: "Wipes", variants: ['12 Pack of Wipes'] },];

const output = Object.values(input.reduce((a, c) => {
  const key = `${c.id}_${c.productType}_${c.variants[0]}`;
  if (!a.hasOwnProperty(key)) {
      a[key] = {...c};
  }
  return a;
}, {}));

console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    • 2019-03-26
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    相关资源
    最近更新 更多