How do you merge consecutive repeating elements in an array?

后端 未结 4 1767
[愿得一人]
[愿得一人] 2020-12-20 17:26

I need to merge consecutive repeating elements in an array, such that

[1, 2, 2, 3, 1]

becomes

[1, 2, 3, 1]
<
相关标签:
4条回答
  • 2020-12-20 18:02
    def remove_consecutive_duplicates(xs)
      [xs.first] + xs.each_cons(2).select do |x,y|
        x != y
      end.map(&:last)
    end
    
    remove_consecutive_duplicates([1, 2, 2, 3, 1])
    #=> [1,2,3,1]
    

    This returns a new array like uniq does and works in O(n) time.

    0 讨论(0)
  • 2020-12-20 18:09

    does !uniq not work for what you are doing?

    http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_array.html

    0 讨论(0)
  • 2020-12-20 18:10

    There is a abstraction in the core that pretty much does the job, Enumerable#chunk:

    xs = [1, 2, 2, 3, 3, 3, 1]
    xs.chunk { |x| x }.map(&:first)
    #=> [1, 2, 3, 1]
    
    0 讨论(0)
  • 2020-12-20 18:23

    sepp2k's answer is already accepted, but here are some alternatives:

    # Because I love me some monkeypatching
    class Array
      def remove_consecutive_duplicates_2
        # Because no solution is complete without inject
        inject([]){ |r,o| r << o unless r.last==o; r }
      end
    
      def remove_consecutive_duplicates_3
        # O(2n)
        map.with_index{ |o,i| o if i==0 || self[i-1]!=o }.compact
      end
    
      def remove_consecutive_duplicates_4
        # Truly O(n)
        result = []
        last   = nil
        each do |o|
          result << o unless last==o
          last = o
        end
        result
      end
    end
    

    And although performance is not everything, here are some benchmarks:

    Rehearsal --------------------------------------------
    sepp2k     2.740000   0.010000   2.750000 (  2.734665)
    Phrogz_2   1.410000   0.000000   1.410000 (  1.420978)
    Phrogz_3   1.520000   0.020000   1.540000 (  1.533197)
    Phrogz_4   1.000000   0.000000   1.000000 (  0.997460)
    ----------------------------------- total: 6.700000sec
    
                   user     system      total        real
    sepp2k     2.780000   0.000000   2.780000 (  2.782354)
    Phrogz_2   1.450000   0.000000   1.450000 (  1.440868)
    Phrogz_3   1.530000   0.020000   1.550000 (  1.539190)
    Phrogz_4   1.020000   0.000000   1.020000 (  1.025331)
    

    Benchmarks run on removing duplicates from orig = (0..1000).map{ rand(5) } 10,000 times.

    0 讨论(0)
提交回复
热议问题