我需要检查两个数组是否包含任何顺序的相同数据。
使用虚构的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
我使用的arr1.sort == arr2.sort
似乎有效,但是有更好的方法吗?
答案 0 :(得分:36)
最简单的方法是使用交叉点:
@array1 = [1,2,3,4,5]
@array2 = [2,3,4,5,1]
所以声明
@array2 & @array1 == @array2
将是true
。如果您想检查array1
是否包含array2
还是相反(不同),这是最佳解决方案。您也没有摆弄阵列或更改项目的顺序。如果希望它们的大小相同,也可以比较两个数组的长度。
这也是最快的方式(如果我错了,请纠正我)
答案 1 :(得分:31)
在比较数组之前对数组进行排序是O(n log n)。此外,正如Victor指出的那样,如果数组包含不可排序的对象,则会遇到麻烦。比较直方图O(n)更快。
你会在Facets中找到Enumerable#frequency,但是如果你更愿意避免添加更多的依赖项,那么你自己实现它,这非常简单:
require 'facets'
[1, 2, 1].frequency == [2, 1, 1].frequency
#=> true
答案 2 :(得分:17)
如果您知道任何数组中没有重复(即,所有元素都是唯一的或您不关心),使用集合是直接且可读的:
Set.new(array1) == Set.new(array2)
答案 3 :(得分:6)
你可以通过monkey patching实现这个#compare
方法,如下所示:
class Array
def compare(other)
sort == other.sort
end
end
请记住,猴子修补很少被认为是一种很好的做法,使用它时应该小心。
可能有一种更好的方法可以做到这一点,但这就是我想到的。希望它有所帮助!
答案 4 :(得分:3)
我找到的最优雅的方式:
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
答案 5 :(得分:3)
您可以打开array
类并定义这样的方法。
class Array
def compare(comparate)
to_set == comparate.to_set
end
end
arr1.compare(arr2)
irb => true
或简单地使用
arr1.to_set == arr2.to_set
irb => true
答案 6 :(得分:0)
这是一个适用于不可排序数组的版本
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)
答案 7 :(得分:0)
如果数组长度相同,则使用差值法 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?
否则,您可以使用
# to check that arrays are equal:
arr1.sort == arr2.sort