class - Guidance on how to implement certain problems in Ruby -
for class numberset
, have define []
method takes 1 argument, uses filter select members of set , returns new set containing elements.
for example, have
filter.new { |number| number.even? }
and
signfilter.new(:non_negative)
which classes must construct.
i have define &
, |
operators work filters. along lines of
numbers[signfilter.new(:non_negative) & filter.new { |number| number.even? }]
the class far is:
class numberset include enumerable def initialize @arr=[] end def each (&block) @arr.each |member| block.call (member) end end def << number @arr<<number unless @arr.include?(number) end end
for filter
think works:
class filter def initialize yield end end
my biggest problem []
, $
and |
parts, have no thought how do.
what want accomplish :
numbers = numberset.new [-3, -2, -1, 0, 1, 2, 3, 4, 5].each |number| numbers << number end numbers[signfilter.new(:non_negative) & filter.new { |number| number.even?}].to_a #=>[0, 2, 4]
i think should it.
code
signfilter class
class signfilter def initialize(sign) @sign = sign end def filter case @sign when :negative -> { < 0 } when :positive -> { > 0 } when :non_negative -> { >= 0 } when :non_positive -> { <= 0 } when :zero -> { i.zero? } end end end
filter class
class filter attr_reader :filter def initialize &filter @filter = filter end end
numberset class
class numberset def initialize arr @arr = arr end def process(op, sf, f) sign_filter = sf.filter filter = f.filter @arr.send(op).each { |e| sign_filter.call(e) } .send(op).each { |e| filter.call(e) } end end
examples
sf = signfilter.new :negative f = filter.new { |number| number.even? } ns = numberset.new [-3, -2, -1, 0, 1, 2, 3, 4, 5] ns.process(:reject, sf, f) #=> [1, 3, 5] sf = signfilter.new :non_negative f = filter.new { |number| number % 3 == 0 } ns = numberset.new [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6] ns.process(:select, sf, f) #=> [0, 3, 6]
explanation
blocks not objects, can't pass them around. can converted procs, however, objects (instances of class proc), , hence can passed. need understand procs (and lambdas, type of proc). here explanation. (aside: 1 thing that's little confusing procs multitude of ways can invoked. example, if p -> { 3*i }
, p.call(2)
, p.yield(2)
, p[2]
, p.(2)
homecoming value 6
.)
here happening:
an instancesf
of signfilter
class created passing symbol denoting signs of elements of array selected or rejected (:negative
, :non_negative
, on). symbol saved in instance variable @sign
. the signfilter
class has method filter
returns lambda
based on value of @sign
. an instance of filter
class created passing block received proc
, saved instance variable @filter
, has read accessor. an instance of numberset
class created passing array, saved instance variable @arr
. numberset#process
passed 3 arguments: enumerable method :reject
or :select
(saved op
), signfilter
instance (sf
) , filter
instance (f
). within numberset#process
, @arr
sent op
, creates enumerator (arr.reject
or arr.select)
. the signfilter
lambda called on each element of enumerator. array comprised of subcollection of @arr
returned. the returned array sent op
, creating reject
or select
enumerator. the filter
proc called on each element of new enumerator, causing desired array returned. considering both reject
, select
not necessary (either do), have been simpler replace .send(op)
in numberset#process
with, say, reject
, chose way illustrate generalization.
notice easy generalize numberset#process
process(sf,f,o)
, where, now, sf
, f
provide filters , o
instance of operation
class specifies proc send filtered subcollection of @arr
invoke enumerable method block (map
, group_by
, on).
ruby class filter
No comments:
Post a Comment