Last active
April 14, 2021 08:00
-
-
Save braindeaf/e4604ed348591e9f27fb83e3621f5307 to your computer and use it in GitHub Desktop.
Extending Ruby Array to add consecutive method.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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