比较两个忽略Ruby中元素顺序的数组

时间:2012-02-01 11:28:51

标签: ruby arrays comparison

我需要检查两个数组是否包含任何顺序的相同数据。 使用虚构的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似乎有效,但是有更好的方法吗?

8 个答案:

答案 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