如何让Lodash的difference方法考虑元素出现的数量差异?
解决Lodash _.difference不考虑元素出现次数的问题
我懂你的困扰——_.difference()确实只判断元素是否存在于第二个数组中,完全忽略了出现次数,所以当arr1里某个元素的数量比arr2多的时候,多出来的部分不会被算进结果里。
要实现你想要的「考虑出现次数的差异」,可以试试下面这两种方法:
方法1:用Lodash countBy统计次数
通过统计两个数组中每个元素的出现次数,计算差值后把arr1里多出来的元素按次数补充到结果中:
function differenceWithCount(arr1, arr2) { // 统计两个数组的元素出现频次 const countMap1 = _.countBy(arr1); const countMap2 = _.countBy(arr2); const result = []; // 遍历arr1的所有唯一元素 Object.entries(countMap1).forEach(([key, count]) => { const element = Number(key); // 如果元素是字符串可省略此步 const arr2Count = countMap2[key] || 0; const surplus = count - arr2Count; // 将多出来的元素批量加入结果 if (surplus > 0) { result.push(...Array(surplus).fill(element)); } }); return result; } // 测试示例 const arr1 = [12285, 2413, 12285]; const arr2 = [12285]; console.log(differenceWithCount(arr1, arr2)); // 输出: [12285, 2413]
方法2:过滤+移除匹配元素实现
这种方法不需要统计次数,而是复制一份arr2,遍历arr1时每匹配到一个元素就从复制的数组里移除,剩下没匹配到的就是我们要的差异:
function differenceWithCount(arr1, arr2) { const tempArr2 = [...arr2]; // 复制arr2避免修改原数组 return arr1.filter(item => { const matchIndex = tempArr2.indexOf(item); if (matchIndex === -1) { return true; // 没匹配到,加入结果 } tempArr2.splice(matchIndex, 1); // 匹配到就从临时数组移除,避免重复匹配 return false; }); } // 测试示例 const arr1 = [12285, 2413, 12285]; const arr2 = [12285]; console.log(differenceWithCount(arr1, arr2)); // 输出: [2413, 12285]
两种方法各有优势:第一种适合数字、字符串这类可哈希的元素,效率更高;第二种可以处理对象等复杂类型(只要把indexOf换成_.findIndex自定义匹配逻辑就行)。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

