JavaScript/Lodash:多维数组获取唯一值并维持指定子数组结构
解决多维数组全局去重并保持子数组4元素结构的方案
我懂你现在的头疼点——处理多维数组的时候,既要保证每个子数组留4个值,又要让整个大数组里的所有值都不重复,之前试的方法要么去重成功了但结构完全不对,甚至用Lodash的_.map也没达到预期效果。我来给你拆解两种常见场景的解决方案,你可以根据自己的实际需求选:
场景1:忽略原数组结构,生成全新的4元素子数组(全局值唯一)
如果你的需求是最终得到一个多维数组,每个子数组固定4个元素,且所有元素在全局范围内完全唯一(不管原数组的子数组划分),可以按以下步骤来:
- 先把多维数组完全扁平化,提取所有值
- 对扁平化后的数组去重
- 将去重后的一维数组重新分割为每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个值,且这些值在整个大数组里不会重复出现(即某个值出现在一个子数组后,其他子数组不能再用),就需要全局跟踪已使用的值,具体逻辑如下:
- 用一个集合来记录已经被选入结果的元素
- 遍历每个原数组的子数组,筛选出未被使用过的元素
- 对当前子数组的筛选结果去重,取前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.
相关产品推荐
相关产品推荐

