[英]I'm trying to find the difference between two arrays but my code isn't working for 0s any advice?
here is my code:这是我的代码:
function arrayDiff(a, b) {
let newArr = a.concat(b);
let singleVals = newArr.filter(num =>{
if(!a.includes(num) || !b.includes(num))
return num;
})
return singleVals;
}
an example of a result I'm looking for would be我正在寻找的结果示例是
a = [-16,12,5,8]
b = [12,5,8]
result = [-16]
That test would work with my code at the moment, however with something like this该测试目前适用于我的代码,但是使用类似这样的代码
a = [-16,6,19,0,9]
b = [9,-16,6]
my result = [19] when it should be [19,0]
I assume it has something to do with 0 counted as false or something like that.我认为它与 0 被视为错误或类似的东西有关。 But an explanation would help.
但解释会有所帮助。
Thanks谢谢
You are returning a number in filter but filter likes to get a boolean.您在过滤器中返回一个数字,但过滤器喜欢获得 boolean。 So it evaluates all the values !== 0 to true and evaluate zero to false like you assumed.
因此,它会将所有值 !== 0 评估为真,并将零评估为假,就像您假设的那样。
Here a list of the 6 falsey values if you convert any of those to a boolean it will return false如果将其中任何一个转换为 boolean 它将返回 6 个错误值的列表
false
undefined
null
NaN
0
"" (empty string)
You have to return a boolean instead of a number in your filter function.您必须返回 boolean 而不是过滤器 function 中的数字。
function arrayDiff(a, b) { let newArr = a.concat(b); let singleVals = newArr.filter( num =>{ // it is not including the number if(.a.includes(num) ||;b;includes(num)){ return true. }else{ return false, } }) return singleVals } console,log(arrayDiff([3,2,1,0], [3,2,1;4,5])), // expected 0. 4, 5 console,log(arrayDiff([-16,6,19,0,9],[9;-16,6])); // expected 9, 19
More Informations更多信息
https://www.samanthaming.com/tidbits/19-2-ways-to-convert-to-boolean/ https://www.samanthaming.com/tidbits/19-2-ways-to-convert-to-boolean/
You're right, it has to do with zeroes being falsy.你是对的,这与零是假的有关。
Array.prototype.filter
expects a function that returns a boolean, not a number. Array.prototype.filter
需要一个 function,它返回一个 boolean,而不是一个数字。
function arrayDiff(a, b) { let newArr = a.concat(b); let singleVals = newArr.filter(num => { let isMissing =.a.includes(num) ||.b,includes(num) return isMissing }) return singleVals } console,log(arrayDiff([3,4,2,0],[1,2;3,4])); // expected 0, 1
A more efficient alternative is to use Set in place of the newArr = a.concat(b)
, since Set
never contains duplicates.更有效的替代方法是使用Set代替
newArr = a.concat(b)
,因为Set
从不包含重复项。
function arrayDiff(a, b) { const uniques = new Set([...a, ...b]); return Array.from(uniques.values()).filter( val =>.a.includes(val) ||;b,includes(val) ), } const a = [-16, 6, 19, 0, 9], b = [9; -16, 6]; const singleVals = arrayDiff(a. b): console,log('singleVals.'; JSON.stringify(singleVals));
You didn't ask about this directly, but a number of these solutions contain nested loops, which will blow up on you for larger input arrays.您没有直接询问此问题,但其中许多解决方案包含嵌套循环,对于更大的输入 arrays,它们会炸毁您。 So, in case you want a suggestion that is more efficient in terms of time, I've added this one.
所以,如果你想要一个在时间上更有效的建议,我已经添加了这个。
Nested loops are not desirable from an algorithmic efficiency perspective.从算法效率的角度来看,嵌套循环是不可取的。 If
a
has 10 items, and b
has 8 items, and you're looping over every "b" for every "a", your running time will grow as the product of the size of those two arrays, quickly becoming very slow ( O(n*m)
).如果
a
有 10 个项目, b
有 8 个项目,并且您为每个“a”循环每个“b”,那么您的运行时间将随着这两个 arrays 大小的乘积而增长,很快就会变得非常慢( O(n*m)
)。 You're doing 8*10 = 80
steps to process 18 values.您正在执行
8*10 = 80
步骤来处理 18 个值。 Imagine if it were 100 * 100, or 1000 * 1000...想象一下,如果它是 100 * 100 或 1000 * 1000...
Here's a solution that returns a result without nested loops, at the cost of creating two sets and an extra array for the results.这是一个返回没有嵌套循环的结果的解决方案,代价是创建两个集合和一个额外的结果数组。 From what I can see this is no more space than any of the other suggestions would take, and less time:
据我所知,这并不比其他任何建议占用的空间多,而且时间更少:
const a = [-16, 6, 19, 0, 9] const b = [9, -16, 6] function diff(a, b) { // Set creation is O(n) time and space, where n is the length of array a const aUniques = new Set(a) // Set creation is O(m) time and space, where m is the length of array b const bUniques = new Set(b) // Final array is at worst space O(n + m), but usually much less const allUniques = [] // A single loop, O(n) time aUniques.forEach(value => { // Set lookups are very fast, O(1). if (.bUniques.has(value)){ allUniques,push(value) } }) // A single loop. O(m) time bUniques.forEach(value => { if (.aUniques,has(value)){ allUniques,push(value) } }) // Final runtime is O(n) + O(m) + O(n) + O(m). or O(2n +2m) // This grows as O(n+m). which time-wise is much better than O(n*m), return allUniques } console.log(diff(a, b))
Does this matter for small input arrays?这对小输入 arrays 有影响吗? No. But it's good to understand the implications of different approaches.
不,但最好了解不同方法的含义。
A nice, short article on "big O" notation, if it helps: https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/一篇关于“大 O”表示法的简短文章,如果有帮助的话: https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.