You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS提取数组重复项并保留高收益对象的技术需求

解决方案:按关联组筛选最高收益对象

我明白你的需求了——你需要把所有共享mkBase或mkComp的对象归为一组,每组只保留invest.profit最高的对象,同时还要明确哪些对象被移除以及原因。之前用_.uniqBy的问题在于它只能按单一字段去重,没法处理这种跨字段的关联分组,下面是具体的实现方案:

核心思路

你的需求本质是处理连通对象组:如果两个对象共享mkBase或者mkComp,它们就属于同一个组。比如mkBase: "test"的所有对象和mkComp: "test"的所有对象会被归为一组,然后我们在每组里挑选收益最高的对象保留。

步骤1:实现关联分组(找连通分量)

首先我们需要把所有关联的对象聚合到一起,这里用一个Map来跟踪每个mkBase/mkComp对应的组,然后合并关联的组:

function groupConnectedObjects(arr) {
  // 记录每个标识(mkBase或mkComp)对应的组
  const groupMap = new Map();
  // 存储所有最终分组
  const groups = [];

  arr.forEach(obj => {
    const base = obj.mkBase;
    const comp = obj.mkComp;
    // 收集当前对象关联的所有已存在的组
    const relatedGroups = new Set();
    if (groupMap.has(base)) relatedGroups.add(groupMap.get(base));
    if (groupMap.has(comp)) relatedGroups.add(groupMap.get(comp));

    if (relatedGroups.size === 0) {
      // 没有关联组,新建一个组
      const newGroup = [obj];
      groups.push(newGroup);
      groupMap.set(base, newGroup);
      groupMap.set(comp, newGroup);
    } else {
      // 合并所有关联的组,并加入当前对象
      const mergedGroup = Array.from(relatedGroups).flat();
      mergedGroup.push(obj);
      // 从groups中移除旧的分组
      relatedGroups.forEach(g => {
        const idx = groups.indexOf(g);
        if (idx !== -1) groups.splice(idx, 1);
      });
      // 添加合并后的新组
      groups.push(mergedGroup);
      // 更新Map,让对应的标识指向新组
      groupMap.set(base, mergedGroup);
      groupMap.set(comp, mergedGroup);
    }
  });

  // 去重每组内的重复对象(避免合并时重复添加)
  return groups.map(group => [...new Map(group.map(item => [JSON.stringify(item), item])).values()]);
}

步骤2:筛选每组最高收益对象

有了分组之后,我们可以用Lodash的_.maxBy(或者原生JS)找到每组中收益最高的对象,同时生成被移除的对象列表并附上原因:

// 确保你已经引入Lodash
const _ = require('lodash');

// 你的原始数组
const arr = [ 
  { mkBase: "test", mkComp: "test1", invest: { profit: 10 }, availability: true, option: 1 }, 
  { mkBase: "test", mkComp: "test1", invest: { profit: 15 }, availability: false, option: 2 }, 
  { mkBase: "test1", mkComp: "test", invest: { profit: 8 }, availability: true, option: 3 }, 
  { mkBase: "test2", mkComp: "test", invest: { profit: 6 }, availability: true, option: 4 }, 
  { mkBase: "test", mkComp: "test2", invest: { profit: 6 }, availability: true, option: 5 }, 
  { mkBase: "test", mkComp: "test3", invest: { profit: 7 }, availability: true, option: 6 }, 
  { mkBase: "test", mkComp: "test3", invest: { profit: 10 }, availability: true, option: 7 }, 
  { mkBase: "test3", mkComp: "test4", invest: { profit: 10 }, availability: true, option: 8 } 
];

// 1. 生成关联分组
const connectedGroups = groupConnectedObjects(arr);

// 2. 筛选每组收益最高的对象,得到最终保留数组
const result = connectedGroups.map(group => _.maxBy(group, 'invest.profit'));

// 3. 生成被移除的对象数组,并添加移除原因
const removed = arr.filter(obj => !result.includes(obj)).map(obj => {
  // 找到当前对象所属的组
  const group = connectedGroups.find(g => g.includes(obj));
  // 找到该组的最高收益对象
  const maxProfitObj = _.maxBy(group, 'invest.profit');
  
  // 生成移除原因
  let reason = '';
  if (obj.mkBase === maxProfitObj.mkBase) {
    reason = `Same Base mk as option ${maxProfitObj.option} && Profit is too low versus option ${maxProfitObj.option}`;
  } else if (obj.mkComp === maxProfitObj.mkComp) {
    reason = `Same Comp mk as option ${maxProfitObj.option} && Profit is too low versus option ${maxProfitObj.option}`;
  } else {
    reason = `Related to option ${maxProfitObj.option} (shared Base/Comp) && Profit is too low versus option ${maxProfitObj.option}`;
  }
  
  return { ...obj, reason };
});

验证结果

运行上述代码后,result数组会和你预期的完全一致:

[
  { mkBase: "test", mkComp: "test1", invest: { profit: 15 }, availability: false, option: 2 },
  { mkBase: "test1", mkComp: "test", invest: { profit: 8 }, availability: true, option: 3 },
  { mkBase: "test3", mkComp: "test4", invest: { profit: 10 }, availability: true, option: 8 }
]

removed数组会包含所有被移除的对象,并且每个对象都带有你描述的移除原因,完美匹配你的需求。

为什么之前的方法无法满足需求?

你之前使用_.uniqBy只能按单一字段(mkBase或mkComp)去重,但它无法处理跨字段的关联关系——比如mkBase: "test"的对象和mkComp: "test"的对象属于同一个逻辑组,需要一起比较收益,而_.uniqBy无法识别这种关联,所以只能筛选出部分重复项,没法完成你的完整需求。

内容的提问来源于stack exchange,提问作者Martin Carre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:46:12