Skip to content

Instantly share code, notes, and snippets.

@braindeaf
Last active April 14, 2021 08:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save braindeaf/e4604ed348591e9f27fb83e3621f5307 to your computer and use it in GitHub Desktop.
Save braindeaf/e4604ed348591e9f27fb83e3621f5307 to your computer and use it in GitHub Desktop.
Extending Ruby Array to add consecutive method.
# I want to take this array and return consecutive groups of numbers that are above or equal to 10.
[7.5, 10, 10, 10, 9, 10, 11]
# Enter, slice_when
[7.5, 10, 10, 10, 9, 10, 11].slice_when { |i, j| i >= 10 && j < 10 || j >= 10 && i < 10 }.select { i >= 10 }
# I don't want to repeat myself all the time, so boring
#
# I'm saying plenty of i >= 10 and j < 10
# So ideally I'd like to pass this test into a method
# e.g [7.5, 10, 10, 10, 9, 10, 11].some_method { |i| i >= 10 || something }
#
# As soon as I do that I realise
# i >= 10 && j < 10
# is basically saying i >= 10 && !(j >= 10)
# so....yielding my block with the test means I can do this.
class Array
#
# consecutive { |i| i >= 10 }
#
def consecutive
slice_when { |i, j| yield(i) != yield(j) }
.select { |h| h.any? { |v| yield(v) } }
end
end
# Which means I can do
# [7.5, 10, 10, 10, 9, 10, 11].consecutive { |i| i >= 10 }
# => [[10, 10, 10], [10, 11]]
# or
# irb(main):006:0> [7.5, 10, 10, 10, 9, 10, 11].consecutive(&:even?)
# Traceback (most recent call last):
# 1: from (irb):6
# NoMethodError (undefined method `even?' for 7.5:Float)
# ok, so 7.5 is not an Integer sso...
# [7, 10, 10, 10, 9, 10, 11].consecutive(&:even?)
# => [[10, 10, 10], [10]]
# [7, 10, 10, 10, 9, 10, 11].consecutive(&:odd?)
# => [[7], [9], [11]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment