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

合并并去重含数组的复杂对象数组:分数合并问题

问题分析与解决方案

你的思路方向是对的,但现有代码存在几个关键问题,导致没达到预期效果:

  1. 调用方式错误:_.uniqBy是函数,应该用圆括号()调用,而不是方括号[],比如_.uniqBy(merged, 'gameId')才是正确写法。
  2. 未处理字段命名差异:arr2中FireNormal的_score、_playerName等带下划线的字段没有转换为标准字段名,直接合并会导致结构不一致。
  3. 嵌套数组去重逻辑缺失:_.uniqBy(merged, '_scores')无法处理嵌套的_scores数组内的重复条目,因为它只会比较整个_scores数组的引用,而不是数组内的具体对象内容。

步骤1:处理字段名转换

先遍历arr2,将所有带下划线的字段转换为标准字段名,同时兼容原有格式:

const processedArr2 = arr2.map(item => {
  return {
    ...item,
    _scores: item._scores.map(score => {
      return {
        score: score._score ?? score.score,
        playerName: score._playerName ?? score.playerName,
        fullCombo: score._fullCombo ?? score.fullCombo,
        timestamp: score._timestamp ?? score.timestamp
      };
    })
  };
});

这里用空值合并运算符??确保不管字段有没有下划线,都能正确映射到标准字段名。

步骤2:合并数组并按gameId分组

使用lodash的_.groupBy将arr1和处理后的arr2合并,按gameId归类:

const combined = [...arr1, ...processedArr2];
const grouped = _.groupBy(combined, 'gameId');

步骤3:合并_scores并去重

对每个分组内的_scores数组进行合并,然后根据score、playerName、fullCombo、timestamp的组合进行去重(这四个字段完全一致才算重复条目):

const mergedArray = Object.values(grouped).map(group => {
  // 合并当前gameId下的所有_scores条目
  const allScores = group.flatMap(item => item._scores);
  // 用字段组合的字符串作为唯一标识去重
  const uniqueScores = _.uniqBy(allScores, score => 
    JSON.stringify([score.score, score.playerName, score.fullCombo, score.timestamp])
  );
  return {
    gameId: group[0].gameId,
    _scores: uniqueScores
  };
});

完整可运行代码

把所有步骤整合起来:

const arr1 = [{ "gameId": "AirNormal", "_scores": [{ "score": 144701, "playerName": "FOO", "fullCombo": true, "timestamp": 1599968866 }] }, { "gameId": "EarthNormal", "_scores": [{ "score": 177352, "playerName": "BAR", "fullCombo": true, "timestamp": 1599969253 }, { "score": 164665, "playerName": "FOO", "fullCombo": false, "timestamp": 1599970971 }] }];
const arr2 = [{ "gameId": "EarthNormal", "_scores": [{ "score": 177352, "playerName": "BASH", "fullCombo": false, "timestamp": 1512969017 }, { "score": 164665, "playerName": "FOO", "fullCombo": false, "timestamp": 1599970971 }] }, { "gameId": "FireNormal", "_scores": [{ "_score": 124701, "_playerName": "FOO", "_fullCombo": true, "_timestamp": 1591954866 }] }];

// 处理arr2的字段名转换
const processedArr2 = arr2.map(item => {
  return {
    ...item,
    _scores: item._scores.map(score => {
      return {
        score: score._score ?? score.score,
        playerName: score._playerName ?? score.playerName,
        fullCombo: score._fullCombo ?? score.fullCombo,
        timestamp: score._timestamp ?? score.timestamp
      };
    })
  };
});

// 合并并分组
const combined = [...arr1, ...processedArr2];
const grouped = _.groupBy(combined, 'gameId');

// 合并scores并去重得到最终结果
const mergedArray = Object.values(grouped).map(group => {
  const allScores = group.flatMap(item => item._scores);
  const uniqueScores = _.uniqBy(allScores, score => 
    JSON.stringify([score.score, score.playerName, score.fullCombo, score.timestamp])
  );
  return {
    gameId: group[0].gameId,
    _scores: uniqueScores
  };
});

console.log(mergedArray);

运行这段代码就能得到你预期的合并结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:39:29