2

Given the Array:

arr = ['a','a','b','b','b','a','c']

Is there a quick way in Ruby to remove repeated consecutive elements, but not all duplicate elements like arr.uniq would? The expected output would be:

['a','b','a','c']

Here's what I've tried. It is possible to iterate over the Array as follows, but what is the cleanest way to do this in Ruby?

def remove_repeats arr
  new_arr       = []
  last_element  = nil
  arr.each do |x|
    if last_element != x
      new_arr << x
    end
    last_element = x
  end
  new_arr
end

arr = ['a','a','b','b','b','a','c','c']
puts remove_repeats(arr).join(',')

# => a,b,a,c
Axiombadger
  • 161
  • 10
  • This perhaps is a duplicate, I was searching for how to operate on the Array class specifically. The other question talks of the more specific terminology lists, which I could have also searched I guess. The other question barely uses the term Array (only in a few comments) and it is the class which is actually being used. That is also why I used Array (with a capital), it is a class. – Axiombadger May 19 '18 at 19:57

2 Answers2

6

Try this one

arr.chunk_while(&:==).map(&:first)

The first step, arr.chunk_while(&:==), makes an array of array of equal values'. You can see the first step's outcome with arr.chunk_while(&:==).to_a. The second step, map(&:first), takes the first item for every subarray and at the end it flattens this n-subarray array.

Ursus
  • 29,643
  • 3
  • 33
  • 50
  • Thanks! That is pretty slick, I will leave the question open a bit for any other input but this was the kind of ruby one-liner answer I was expecting would exist. – Axiombadger May 19 '18 at 14:24
  • 2
    Note that since Ruby 2.2 the first step can also be written as `arr.chunk(&:itself)`. Also your solution works fine with `map`, no need to use `flat_map` here. – Michael Kohl May 19 '18 at 16:13
  • 2
    if array conatin on single letters then you can use `arr.join.squeeze.split('')` or insteatd of chunk while or flat_map use : `arr.chunk(&:itself).map(&:first)` it is more optimized Thanks! – rahul mishra May 19 '18 at 16:16
  • 1
    if you have `facets gem` link: https://github.com/rubyworks/facets then you can simply use `arr.squeeze!` ref:https://www.rubydoc.info/github/rubyworks/facets/Array:squeeze! – rahul mishra May 19 '18 at 16:27
  • Thanks for the suggestions you all :) – Ursus May 19 '18 at 19:23
  • Thank you all, I am actually using this with words not single characters although it is good to see the single character solution as well. – Axiombadger May 19 '18 at 19:50
0

Try arr.uniq!, it removes all duplicates in place.

Victor
  • 32
  • 6