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

JavaScript/Lodash:多维数组获取唯一值并维持指定子数组结构

解决多维数组全局去重并保持子数组4元素结构的方案

我懂你现在的头疼点——处理多维数组的时候,既要保证每个子数组留4个值,又要让整个大数组里的所有值都不重复,之前试的方法要么去重成功了但结构完全不对,甚至用Lodash的_.map也没达到预期效果。我来给你拆解两种常见场景的解决方案,你可以根据自己的实际需求选:

场景1:忽略原数组结构,生成全新的4元素子数组(全局值唯一)

如果你的需求是最终得到一个多维数组,每个子数组固定4个元素,且所有元素在全局范围内完全唯一(不管原数组的子数组划分),可以按以下步骤来:

  1. 先把多维数组完全扁平化,提取所有值
  2. 对扁平化后的数组去重
  3. 将去重后的一维数组重新分割为每4个元素一组的子数组

用Lodash实现的代码示例:

const _ = require('lodash');

// 示例原多维数组
const originalArray = [
  [1, 2, 3, 4, 5, 2],
  [6, 7, 8, 9, 1, 10],
  [11, 7, 12, 13, 14, 4]
];

// 扁平化+全局去重
const uniqueFlatList = _.uniq(_.flattenDeep(originalArray));

// 分割为4元素子数组
const result = [];
for (let i = 0; i < uniqueFlatList.length; i += 4) {
  result.push(uniqueFlatList.slice(i, i + 4));
}

console.log(result);
// 输出:[[1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14]]

场景2:保留原数组的子数组结构,每个子数组最多4个全局唯一值

如果需要保留原来的子数组划分,只是每个子数组里只留最多4个值,且这些值在整个大数组里不会重复出现(即某个值出现在一个子数组后,其他子数组不能再用),就需要全局跟踪已使用的值,具体逻辑如下:

  1. 用一个集合来记录已经被选入结果的元素
  2. 遍历每个原数组的子数组,筛选出未被使用过的元素
  3. 对当前子数组的筛选结果去重,取前4个加入结果
  4. 将选中的元素标记为已使用

代码示例:

const _ = require('lodash');

const originalArray = [
  [1, 2, 3, 4, 5, 2],
  [6, 7, 8, 9, 1, 10],
  [11, 7, 12, 13, 14, 4]
];

const usedValues = new Set();
const result = [];

_.forEach(originalArray, (subArr) => {
  // 筛选当前子数组中未被使用的元素
  const unusedItems = _.filter(subArr, item => !usedValues.has(item));
  // 去掉当前子数组内的重复值
  const uniqueUnused = _.uniq(unusedItems);
  // 取前4个(不足4个就取全部)
  const selected = uniqueUnused.slice(0, 4);
  // 标记选中值为已使用
  selected.forEach(item => usedValues.add(item));
  result.push(selected);
});

console.log(result);
// 输出:[[1,2,3,4], [6,7,8,9], [11,12,13,14]]

为什么单独用_.map没效果?

_.map的作用是遍历每个子数组并做独立转换,它没有全局状态的跟踪能力。如果只靠_.map,只能处理单个子数组内的去重,没法保证跨子数组的全局唯一性——这就是你之前用_.map没达到预期的原因,必须结合全局的状态管理(比如上面的Set)才能实现全局去重的逻辑。

内容的提问来源于stack exchange,提问作者Hamza L.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:31:49