Comparing two arrays ignoring element order in Ruby

后端 未结 8 550
春和景丽
春和景丽 2020-12-08 02:14

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         


        
相关标签:
8条回答
  • 2020-12-08 02:25

    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!

    0 讨论(0)
  • 2020-12-08 02:27

    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
    
    0 讨论(0)
  • 2020-12-08 02:33

    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)
    
    0 讨论(0)
  • 2020-12-08 02:34

    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
    
    0 讨论(0)
  • 2020-12-08 02:36

    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
    
    0 讨论(0)
  • 2020-12-08 02:37

    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)
    
    0 讨论(0)
提交回复
热议问题