如何从Map的对象数组中提取基于首个元素去重的唯一值?
如何从Map的对象数组中提取基于首个元素去重的唯一值?
嗨,我太懂你的困扰了——直接用扩展运算符加Set去重不管用,核心原因是数组是引用类型,哪怕两个数组内容完全一致,Set也会把它们当成不同的元素,所以name2才会重复出现在结果里。不过别发愁,我们换个思路,瞄准每个data数组的第一个元素(也就是那个name值)来做去重,就能轻松得到你想要的结果啦。
我给你整理了一个简单的实现方案,逻辑很清晰:
第一步:先把Map里所有有效的data数组提取出来
先把Map中所有值取出来,把嵌套的数组打平,再提取每个对象里的data字段,顺便过滤掉空数组,避免无用数据干扰后续处理。
第二步:根据第一个元素做去重
用一个临时的Set来记录已经见过的name,遍历提取到的data数组:如果当前数组的第一个元素(name)没在Set里,就把它加入Set并保留这个数组;如果已经存在,就直接过滤掉。
话不多说,直接上代码:
const map = new Map(); map.set('a', [{ data: ['name1', true, true] }, { data: ['name2', false, true] }]); map.set('b', [{ data: ['name3', true, true] }, { data: ['name2', false, true] }]); map.set('c', []); // 提取并去重的完整逻辑 const seenNames = new Set(); const uniqueData = Array.from(map.values()) .flat() // 把Map里的所有对象数组合并成一个一维数组 .map(item => item.data) // 取出每个对象的data数组 .filter(arr => { // 跳过空数组,以及第一个元素已经出现过的数组 if (!arr.length || seenNames.has(arr[0])) { return false; } seenNames.add(arr[0]); return true; }); console.log(uniqueData); // 输出正好是你要的结果: // [ ['name1', true, true], ['name2', false, true], ['name3', true, true] ]
我再给你拆解下关键细节:
Array.from(map.values())能快速拿到Map里所有的数组(也就是a、b、c对应的那三组数据);flat()把嵌套的数组结构打平,变成一个包含所有{data: [...]}对象的一维数组,方便后续处理;- 用Set存name是因为它的
has()和add()方法效率特别高,判断和添加操作都是O(1)的时间复杂度,处理大量数据也不会卡; - 过滤时顺便检查数组长度,能避免空的data数组混入最终结果里。
如果你偏爱更紧凑的写法,也可以把代码合并成一段,逻辑是完全一致的。这样处理后,不管同一个name出现多少次,只会保留第一次出现的那个data数组,完美解决你的问题~
备注:内容来源于stack exchange,提问作者T Rao
相关产品推荐
相关产品推荐

