比较两个数组而忽略 Ruby 中的元素顺序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9095017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing two arrays ignoring element order in Ruby
提问by SimonMayer
I need to check whether two arrays contain the same data in any order.
Using the imaginary comparemethod, I would like to do:
我需要检查两个数组是否以任何顺序包含相同的数据。使用虚构的compare方法,我想做:
arr1 = [1,2,3,5,4]
arr2 = [3,4,2,1,5]
arr3 = [3,4,2,1,5,5]
arr1.compare(arr2) #true
arr1.compare(arr3) #false
I used arr1.sort == arr2.sort, which appears to work, but is there a better way of doing this?
我使用了arr1.sort == arr2.sort,这似乎有效,但有没有更好的方法来做到这一点?
采纳答案by tokland
Sorting the arrays prior to comparing them is O(n log n). Moreover, as Victor points out, you'll run into trouble if the array contains non-sortable objects. It's faster to compare histograms, O(n).
在比较它们之前对数组进行排序是 O(n log n)。此外,正如 Victor 指出的那样,如果数组包含不可排序的对象,您会遇到麻烦。比较直方图更快,O(n)。
You'll find Enumerable#frequencyin Facets, but implement it yourself, which is pretty straightforward, if you prefer to avoid adding more dependencies:
您将在 Facets 中找到Enumerable#frequency,但如果您不想添加更多依赖项,则可以自己实现它,这非常简单:
require 'facets'
[1, 2, 1].frequency == [2, 1, 1].frequency
#=> true
回答by MMM
The easiest way is to use intersections:
最简单的方法是使用交叉点:
@array1 = [1,2,3,4,5]
@array2 = [2,3,4,5,1]
So the statement
所以声明
@array2 & @array1 == @array2
Will be true. This is the best solution if you want to check whether array1contains array2or the opposite (that is different). You're also not fiddling with your arrays or changing the order of the items. You can also compare the length of both arrays if you want them to be identical in size.
会true。如果您想检查是否array1包含array2或相反(即不同),这是最好的解决方案。您也不会摆弄数组或更改项目的顺序。如果您希望它们的大小相同,您还可以比较两个数组的长度。
It's also the fastest way to do it (correct me if I'm wrong)
这也是最快的方法(如果我错了,请纠正我)
回答by Gunchars
If you know that there are no repetitions in any of the arrays (i.e., all the elements are unique or you don't care), using sets is straight forward and readable:
如果您知道任何数组中都没有重复(即,所有元素都是唯一的或者您不在乎),则使用集合是直接且可读的:
Set.new(array1) == Set.new(array2)
回答by Tomislav Dyulgerov
You can actually implement this #comparemethod by monkey patchingthe Array class like this:
您实际上可以#compare通过像这样修补Array 类来实现此方法:
class Array
def compare(other)
sort == other.sort
end
end
Keep in mind that monkey patching is rarely considered a good practice and you should be cautious when using it.
请记住,猴子补丁很少被认为是一种好的做法,在使用它时应谨慎。
There's probably is a better way to do this, but that's what came to mind. Hope it helps!
可能有更好的方法来做到这一点,但这就是我想到的。希望能帮助到你!
回答by Datt
You can open arrayclass and define a method like this.
您可以打开array类并定义这样的方法。
class Array
def compare(comparate)
to_set == comparate.to_set
end
end
arr1.compare(arr2)
irb => true
OR use simply
或简单地使用
arr1.to_set == arr2.to_set
irb => true
回答by Lukasz Muzyka
The most elegant way I have found:
我发现的最优雅的方式:
arr1 = [1,2,3,5,4]
arr2 = [3,4,2,1,5]
arr3 = [3,4,2,1,5,5]
(arr1 - arr2).empty?
=> true
(arr3 - arr2).empty?
=> false
回答by bmalets
Use difference method if length of arrays are the same https://ruby-doc.org/core-2.7.0/Array.html#method-i-difference
如果数组的长度相同,则使用差异方法 https://ruby-doc.org/core-2.7.0/Array.html#method-i-difference
arr1 = [1,2,3]
arr2 = [1,2,4]
arr1.difference(arr2) # => [3]
arr2.difference(arr1) # => [4]
# to check that arrays are equal:
arr2.difference(arr1).empty?
Otherwise you could use
否则你可以使用
# to check that arrays are equal:
arr1.sort == arr2.sort
回答by G. Allen Morris III
Here is a version that will work on unsortable arrays
这是一个适用于不可排序数组的版本
class Array
def unordered_hash
unless @_compare_o && @_compare_o == hash
p = Hash.new(0)
each{ |v| p[v] += 1 }
@_compare_p = p.hash
@_compare_o = hash
end
@_compare_p
end
def compare(b)
unordered_hash == b.unordered_hash
end
end
a = [ 1, 2, 3, 2, nil ]
b = [ nil, 2, 1, 3, 2 ]
puts a.compare(b)

