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

Sim*_*yer 48 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
Run Code Online (Sandbox Code Playgroud)

我用过arr1.sort == arr2.sort,似乎有用,但是有更好的方法吗?

MMM*_*MMM 36

最简单的方法是使用交叉点:

@array1 = [1,2,3,4,5]
@array2 = [2,3,4,5,1]
Run Code Online (Sandbox Code Playgroud)

所以声明

@array2 & @array1 == @array2
Run Code Online (Sandbox Code Playgroud)

会的true.如果要检查是否array1包含array2或相反(即不同),这是最佳解决方案.您也没有摆弄阵列或更改项目的顺序.如果希望它们的大小相同,也可以比较两个数组的长度.

这也是最快的方法(如果我错了,请纠正我)

  • 因此,对于一个完整的答案,`a.size == b.size和a&b == a`实现为`compare(a,b)`方法或猴子补丁. (9认同)
  • 不,它没有.`a = [1,2,3,4,5,1]; b = [1,1,2,3,4,5]; (a.size == b.size)&&(a&b == a)``=> false`,但应该是'true`,因为数组包含相同的项目,只是顺序不同.如果允许数组包含重复条目,则union(`&`)解决方案无法正常工作. (4认同)
  • 这个解决方案(即使有大小检查)在所有情况下都不起作用 - 应该更新答案以澄清这一点,所以它不会让人们误会(参见 SimonMayer 的 [3,4,2,1,5,5] 示例)和 [1,2,3,5,4,4]) (2认同)

tok*_*and 32

在比较数组之前对数组进行排序是O(n log n).此外,正如Victor指出的那样,如果数组包含不可排序的对象,则会遇到麻烦.比较直方图O(n)更快.

您可以在Facets中找到Enumerable#frequency,但是如果您希望避免添加更多依赖项,请自行实现,这非常简单:

require 'facets'
[1, 2, 1].frequency == [2, 1, 1].frequency 
#=> true
Run Code Online (Sandbox Code Playgroud)

  • Ruby 2.7 等效项为 `arr1.tally` == `arr2.tally` (4认同)

Gun*_*ars 18

如果您知道任何数组中没有重复(即,所有元素都是唯一的或您不关心),则使用集合是直接且可读的:

Set.new(array1) == Set.new(array2)
Run Code Online (Sandbox Code Playgroud)


Tom*_*rov 6

你实际上可以#compare通过猴子修补 Array类来实现这个方法,如下所示:

class Array
  def compare(other)
    sort == other.sort
  end
end
Run Code Online (Sandbox Code Playgroud)

请记住,猴子修补很少被认为是一种好习惯,使用它时应该小心谨慎.

可能有更好的方法来做到这一点,但这就是我想到的.希望能帮助到你!