如何比较两个数组的内容?

30

我正在比较邮政编码。

我有三个邮政编码的常数:

ZIP_MORRIS
ZIP_UNION
ZIP_ESSEX

我想查看一个用户在一个对象的数组中,是否包含所有这些zip码。

我尝试了这个:

ZIP_UNION.sort{|x,y| y <=> x} <=> Email.find(3).distributions.map(&:zip_code).uniq.compact.sort{|x,y| y <=> x}

不幸的是,这只是将所有邮政编码进行映射,因此如果我选择另一个县的一个额外邮编,则它将无法正确比较它们。

我认为最好的解决方案是比较用户生成的邮编值,并查看一个ZIP_COUNTY中的所有邮编是否都包含在数组中。

一种迭代器可以遍历所有邮编,并确保用户的邮编是否包括一个邮编组中的每个邮编。

有什么想法吗?

4个回答

85

你可以进行数组差异操作,如果结果是空数组,则表示两个数组包含相同的元素:

>> [1,2,3]-[3,1,2] #=> []
如果您仍有元素剩余,则说明第一个数组中并非所有的元素都在第二个数组中出现:
>> [1,2,5]-[3,1,2] #=> [5]

1
@Trip:从必要性中获得简单。在我们的应用程序中,我经常需要处理多达数十万个元素的ID数组,而其他所有方法都被证明速度太慢。 - Michael Kohl
17
这个解决方案适用于@Trip问题中的特定示例,但不适用于一般情况。你需要进行两次差集运算:

元素数量不匹配

[1] - [1,2] #=> [] [1,2] - [1] #=> [2]

元素内有重复

[1,1,2] - [2,2,1] #=> [] [2,2,1] - [1,1,2] #=> []
- bobics
1
@bobics 我给你的评论点了赞,但它也被发布为回答 Trip 的问题,而不是一般情况下的回答。 - Michael Kohl
1
这个解决方案很优雅,但是当第一个数组为空时,例如[] - [3,1,2] #=> [],它也会失败。 - carbonr
3
先检查长度! - penner

11

以下我在数组上使用all?运算符,如果数组中的所有项都针对我传递的块返回true,则该运算符将返回true。

my_zip = [1,2,3,4,5,6]
[2,3,5].all?{|z| my_zip.include?(z)}
=> true 
[20,3,5].all?{|z| my_zip.include?(z)}
=> false

你只需将其更改为用户的邮政编码即可。


几乎……我已经选择了它们所有,所以它应该返回true。但是它没有。我猜测这是因为它还包括其他不一定在my_zip中的压缩文件,并且认为不是。 - Trip
1
根据这两个数组的长度,这可能会非常缓慢。 - Michael Kohl

7
> [1,2,3] <=> [1,2,3]
=> 0
> [1,2,3] <=> [2,2,3]
=> -1
> [1,2,3] <=> [3,2,3]
=> -1
> [1,2,3] <=> [1,3,3]
=> -1
> [1,2,3] <=> [1,1,3]
=> 1

这段内容来自RailsThinker博客,对于我来说非常有效。


谢谢!这是一个很棒的运算符,特别是当你想比较语义版本时! - MhdSyrwan

3

再做一个决定

arr1 = [3,2,1]
arr2 = [2,1,3]

arr1.sort == arr2.sort # => true

arr2 = [2,1,2]

arr1.sort == arr2.sort # => false

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接