Thanks for your suggestion. I have try to refactor my code as list
below:
def self.count file,min,max
tags = Hash.new(0)
if min && max
counter = lambda {|seq,mi,ma| tags[seq] += 1 if seq.size.between?
mi,ma }
elsif min.nil? && max
counter = lambda {|seq,mi,ma| tags[seq] += 1 if seq.size <= ma }
elsif max.nil? && min
counter = lambda {|seq,mi,ma| tags[seq] += 1 if seq.size >= mi }
else
counter = lambda {|seq,mi,ma| tags[seq] += 1 }
end
File.open(file,“r”).each_slice(4) do |_id,seq,*|
counter.call seq.chomp, min, max
end
end
Dave A. wrote in post #1121565:
On Mon, Sep 16, 2013 at 11:36 AM, felix chang [email protected]
wrote:
Yes! you can see, my code is redundant. But I dont know how to reduce
it.
Does any body have some suggestion?
Yes. First, take a look at the pattern in which your code varies.
Each piece is of the form:
if some varying condition depending on min and max
something constant do |r|
do another constant thing
do some other constant thing if another varying condition of
min, max, and a block-var
end
end
Since you have an “else” block that is likewise of this form, all
possibilities are covered. So, let’s see if we can take this out of
the if. Then we have:
File.open(file,“r”).each_slice(4) do |r|
seq = r[1].chomp
tags[seq] += 1 if we should increment
end
and we just need to define “we should increment”. We could put a
logical expression there, that looks at the various things needed to
make the decision (looks at the first condition and applies the
appropriate second condition), but that could get rather hairy. So
what I would advise in this case is to extract that to a method that
accepts those parameters, and gives back a true or false. (I’ll leave
that as an exercise for the reader.) Then call that where it says “we
should increment”.
-Dave