Skip to content

Instantly share code, notes, and snippets.

@kaspth
Last active June 6, 2019 21:30
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save kaspth/c8edc71695b59f2937af732a521ae1c5 to your computer and use it in GitHub Desktop.
Playground: test `segment` as a more broad `partition`.
# Ruby's Enumerable has `partition` to split it into true and false groups.
evens, odds = 1.upto(5).partition(&:even?)
evens # => [ 2, 4 ]
odds # => [ 1, 3, 5 ]
# But what if you have more than 2 segments? Well, here I'm playing with one way to do it.
# Respectively outputs:
# [[:first, :first], [:second, :second], [:third, :third]]
# [[:first, :first], [:second, :third, :second, :third]]
# [[:first, :first], [:second, :third, :second, :third]]
# [[:first, :first], [:second, :second], [:third, :third]]
p %i( first second third first second third ).segment(&:itself)
p %i( first second third first second third ).segment { |i| i == :first } # Equal to `partition`.
p %i( first second third first second third ).segment { |i| i == :first ? 1 : 2 }
p %i( first second third first second third ).segment { |i| i == :first ? 1 : (i == :second ? 2 : 3) }
class Array
# Basically `partition` with more than true/false as grouping.
def segment(&block)
Hash.new.tap do |segmented|
each do |item|
(segmented[yield(item)] ||= []) << item
end
end.values
end
end
require 'active_support'
require 'active_support/core_ext/enumerable' # For `group_by`.
class Array
# Basically `partition` with more than true/false as grouping.
def segment(&block)
group_by(&block).values
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment