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

发布于 2025-01-01 12:15:13 字数 240 浏览 4 评论 0原文

我需要检查两个数组是否以任何顺序包含相同的数据。 使用想象的比较方法,我想做:

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,这似乎有效,但是有更好的方法吗这?

I need to check whether two arrays contain the same data in any order.
Using the imaginary compare method, I would like to do:

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

妥活 2025-01-08 12:15:14

这是一个适用于不可排序数组的版本

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)

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)
小巷里的女流氓 2025-01-08 12:15:14

如果数组长度相同,则使用差分法
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

Use difference method if length of arrays are the same
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
浪菊怪哟 2025-01-08 12:15:13

最简单的方法是使用交集:

@array1 = [1,2,3,4,5]
@array2 = [2,3,4,5,1]

因此该语句

@array2 & @array1 == @array2

将为 true。如果您想检查 array1 是否包含 array2 或相反(即不同),这是最好的解决方案。您也不会摆弄数组或更改项目的顺序。

如果您希望两个数组的大小相同,您还可以比较它们的长度:

@array1.size == @array2.size && @array1 & @array2 == @array1

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

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 array1 contains array2 or 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:

@array1.size == @array2.size && @array1 & @array2 == @array1

It's also the fastest way to do it (correct me if I'm wrong)

别把无礼当个性 2025-01-08 12:15:13

在比较之前对数组进行排序的时间复杂度为 O(n log n)。此外,正如 Victor 指出的那样,如果数组包含不可排序的对象,您将会遇到麻烦。比较直方图更快,O(n)。

您会在 Facets 中找到 Enumerable#Frequency,但要实现它如果您希望避免添加更多依赖项,那么这非常简单:

require 'facets'
[1, 2, 1].frequency == [2, 1, 1].frequency 
#=> true

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).

You'll find Enumerable#frequency in Facets, but implement it yourself, which is pretty straightforward, if you prefer to avoid adding more dependencies:

require 'facets'
[1, 2, 1].frequency == [2, 1, 1].frequency 
#=> true
等数载,海棠开 2025-01-08 12:15:13

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

Set.new(array1) == Set.new(array2)

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)
雨后咖啡店 2025-01-08 12:15:13

实际上,您可以通过猴子修补 Array 类来实现此#compare 方法像这样:

class Array
  def compare(other)
    sort == other.sort
  end
end

请记住,猴子修补很少被认为是一种好的做法,使用它时应该小心谨慎。

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

You can actually implement this #compare method by monkey patching the Array class like this:

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!

紫轩蝶泪 2025-01-08 12:15:13

我发现的最优雅的方式:

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

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
丶视觉 2025-01-08 12:15:13

您可以打开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

You can open array class and define a method like this.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文