5

I'd like to know whether two Ruby arrays have the same elements, though not necessarily in the same order. Is there a native way to do this? The equality operators for Array seem to check whether the items are the same and the order is the same, and I need to relax the latter condition.

This would be extremely easy to write, I just wonder if there's a native idiom.

Steve Lane
  • 759
  • 1
  • 5
  • 13
  • If contents of your arrays are comparable, you can just sort them before comparison. – 9000 Apr 20 '13 at 12:19
  • 3
    Is there a possibility that an array have the same element twice or more? If so, what do you want to do with it? – sawa Apr 20 '13 at 13:09
  • Possible duplicate of [Comparing two arrays in Ruby](http://stackoverflow.com/questions/9095017/comparing-two-arrays-in-ruby) – Anderson Green Jun 29 '16 at 19:35

4 Answers4

9

If you don't have duplicate items either, you could use Set instead of Array:

Set implements a collection of unordered values with no duplicates. This is a hybrid of Array's intuitive inter-operation facilities and Hash's fast lookup.

Example:

require 'set'
s1 = Set.new [1, 2, 3]   # -> #<Set: {1, 2, 3}>
s2 = [3, 2, 1].to_set    # -> #<Set: {3, 2, 1}>
s1 == s2                 # -> true
Stefan
  • 109,145
  • 14
  • 143
  • 218
6
[2,1].uniq.sort == [1,2].uniq.sort #=> true
[2,1,4].uniq.sort == [1,2].uniq.sort #=> false

or

a1 = [1,2,3]
a2 = [2,3,1]
p (a2-a1).empty? && (a1-a2).empty? #=> true

a1 = [1,2,3]
a2 = [4,3,1]
p (a2-a1).empty? && (a1-a2).empty? #=> false

a1 = [1,2,3]
a2 = [2,3,1,5]
p (a2-a1).empty? && (a1-a2).empty? #=> false
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
4

This would be extremely easy to write, I just wonder if there's a native idiom.

I'm afraid there's no native idiom for it.

If your arrays contains multiple values that you want to count on both arrays you'll have to use #sort to put them in the same order. Once you have done that you can easily compare them:

a.sort == b.sort

Otherwise you can use #uniq that will extract the unique values of the arrays (to make it faster) and use #sort like above:

a.uniq.sort == b.uniq.sort
Shoe
  • 74,840
  • 36
  • 166
  • 272
0
a1 = [1, 2, 3, 4]
a2 = [4, 2, 1, 3]
(a1 & a2).size == a1.size # => true

a3 = [1, 2, 3, 5]
(a1 & a3).size == a1.size # => false
AGS
  • 14,288
  • 5
  • 52
  • 67