Sha256: 53e37971e04154ea42eff33cfacbd94103da4a31cd70b63bb3943bb7d254b787
Contents?: true
Size: 1.73 KB
Versions: 6
Compression:
Stored size: 1.73 KB
Contents
require 'facets/functor' module Enumerable # Accumulate a set of a set. For example, in an ORM design # where `Group has_many User` we might have something # equivalent to the following. # # Group = Struct.new(:users) # User = Struct.new(:name, :friends) # # user1 = User.new('John', []) # user2 = User.new('Jane', ['Jill']) # user3 = User.new('Joe' , ['Jack', 'Jim']) # # group1 = Group.new([user1, user2]) # group2 = Group.new([user2, user3]) # # groups = [group1, group2] # # Now we can *accumulate* the users of all groups. # # groups.accumulate.users #=> [user1, user2, user3] # # You may pass an argument to perform chains, e.g. the following # returns the names of users from all groups. # # groups.accumulate(2).users.name #=> ['John','Jane','Joe'] # # Or we can gather all the friends of all users in groups. # # groups.accumulate(2).users.friends #=> ['Jill','Jack','Jim'] # # This is more convenient then the equivalent. # # groups.accumulate.users.accumulate.friends #=> ['Jill','Jack','Jim'] # # CREDIT: George Moshchovitis, Daniel Emirikol def accumulate(iterations=1) return self if iterations == 0 Functor.new do |op, *args| result = inject([]) { |a, x| a << x.send(op, *args) }.flatten.uniq result.accumulate(iterations - 1) end end # Same as #accumulate, but does not apply #uniq to final result. # # groups.accumulate_all(2).users.friends #=> ['Jill', 'Jill','Jack','Jim'] # def accumulate_all(iterations=1) return self if iterations == 0 Functor.new do |op, *args| result = inject([]) { |a, x| a << x.send(op, *args) }.flatten result.accumulate_all(iterations - 1) end end end
Version data entries
6 entries across 5 versions & 1 rubygems