Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you replace repeating elements in an array?

Tags:

arrays

ruby

I have an array:

[1, 4, 4, 4, 2, 9, 0, 4, 3, 3, 3, 3, 4]

and want to replace the repeating values with a string "repeat". The repeated 4 at indices 1, 2, 3 and 3 at indices 8, 9, 10, 11 should be replaced. I should get:

[1, "repeat", 2, 9, 0, 4, "repeat", 4]

How is this accomplished?

like image 680
Adrian Booth Avatar asked Jun 22 '26 19:06

Adrian Booth


1 Answers

Here are two ways you could do that.

#1 Use Enumerable#chunk:

arr = [1,4,4,4,2,9,0,4,3,3,3,3,4]

arr.chunk(&:itself).map { |f,a| a.size==1 ? f : "repeat" }
  #=> [1, "repeat", 2, 9, 0, 4, "repeat", 4]

The steps:

enum = arr.chunk(&:itself)
  #=> #<Enumerator: #<Enumerator::Generator:0x007febc99fb160>:each>

We can view the elements of this enumerator by converting it to an array:

enum.to_a
  #=> [[1, [1]], [4, [4, 4, 4]], [2, [2]], [9, [9]], [0, [0]],
  #    [4, [4]], [3, [3, 3, 3, 3]], [4, [4]]]

Object#itself was added in Ruby v2.2. For earlier version you would use

enum = arr.chunk { |e| e }

It is now a simple matter to map the elements of enum as required:

enum.map { |f,a| a.size==1 ? f : "repeat" }
  #=> [1, "repeat", 2, 9, 0, 4, "repeat", 4]

#2 Use Enumerable#slice_when

arr.slice_when { |e,f| e !=f }.map { |a| a.size==1 ? a.first : "repeat" } 

The steps:

enum = arr.slice_when { |e,f| e !=f } 
  #=> #<Enumerator: #<Enumerator::Generator:0x007febc99b8cc0>:each> 
a = enum.to_a
  #=> [[1], [4, 4, 4], [2], [9], [0], [4], [3, 3, 3, 3], [4]] 
a.map { |a| a.size==1 ? a.first : "repeat" } 
  #=> [1, "repeat", 2, 9, 0, 4, "repeat", 4]

slice_when was introduced in Ruby v.2.2.

like image 80
Cary Swoveland Avatar answered Jun 25 '26 12:06

Cary Swoveland



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!