[英]How to get the difference between two arrays in JavaScript with repeating values
如何检查一个数组是否包含在另一个数组中并返回缺失值? 我在这篇文章中找到了这样做的方法,但没有考虑到数组中的重复值。 例如,我正在尝试做这样的事情:
getDiff([1, 2, 3], [1, 2, 3, 4]) --> []
getDiff([1, 2, 2, 3], [1, 2, 3, 4]) --> [2]
getDiff(["A", "B", "C"], ["B", "B", "A", "C"]) --> []
getDiff(["B", "B", "B"], [3, 2, 1]) --> ["B", "B", "B"]
一种可能的方法:
function getRepeatingDiff(source, diffed) { const diffedCounter = diffed.reduce((acc, el) => { acc[el] = (acc[el] || 0) + 1 return acc; }, {}); const diff = source.reduce((acc, el) => { return diffedCounter[el]-- > 0 ? acc : [ ...acc, el ]; }, []); return diff; } console.log( getRepeatingDiff([1, 2, 3], [1, 2, 3, 4]) ); console.log( getRepeatingDiff([1, 3, 2, 2, 3], [1, 2, 3, 4]) ); console.log( getRepeatingDiff(["A", "B", "C"], ["B", "B", "A", "C"]) ); console.log( getRepeatingDiff(["B", "B", "B"], [3, 2, 1]) );
从本质上讲,这是一个两步过程:计算diffed
数组中的项目数,然后再遍历一次source
数组 - 并为diffedCounter
缺少的每个副本将一个新项目添加到diff
结果数组中。 但是,这个特定的实现有一个缺陷:因为它使用 Object 来收集计数,所以在计算元素时,它不区分3
作为数字和'3'
作为字符串。
这可能以两种不同的方式修复:要么切换到 Map(但这会使代码更复杂,因为没有诸如递减 map 值之类的事情) - 或者在创建计数器键时仅使用类型前缀。 这是基于前者的方法:
function getRepeatingDiff(source, diffed) { const diffedCounter = diffed.reduce((map, el) => { const prev = map.get(el); return map.set(el, (prev || 0 ) + 1); }, new Map()); const diff = source.reduce((acc, el) => { const remainingCount = diffedCounter.get(el); if (remainingCount) diffedCounter.set(el, remainingCount - 1); return remainingCount ? acc : [ ...acc, el ]; }, []); return diff; } console.log( getRepeatingDiff([1, 2, 3], [1, 2, 3, 4]) ); console.log( getRepeatingDiff([1, 3, 2, 2, 3], [1, 2, 3, 4]) ); console.log( getRepeatingDiff(["A", "B", "C"], ["B", "B", "A", "C"]) ); console.log( getRepeatingDiff(["B", "B", "B"], [3, 2, 1]) );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.