ruby - Why is my code entering a string when I explicitly convert into an int, ONLY for one specific output? -
this i'm working on right now.
here code (feel free critique it, , please do).
def order_weight(weights) weightslist = weights.split(" ") def convert(weight) weight.split("").reduce{|sum,n| sum.to_i + n.to_i} end weightsconv = weightslist.map {|weight| convert(weight)} weightslist.sort_by{|a| [weightsconv[weightslist.index(a)],a]}.join(" ") end
this works on everything except following input string: order_weight("3 16 9 38 95 1131268 49455 347464 59544965313 496636983114762 85246814996697")
in case (by printing), see first 3 entries in weightsconv corrupted "3", "7", "9". else stays same. solved adding .map{|n| n.to_i}
@ end of line 7. don't understand why necessary, since i'm converting inside previous block. goes wrong inside one input? ruby bug?
no, it's bug.
from enumerable#reduce
documentation:
if not explicitly specify initial value memo, first element of collection used initial value of memo.
that's reason you've written sum.to_i
because sum
string in case. if collection has 1 element (such ["3"]
) there no need invoke block because documentation says return value first element (which "3"
). code can fixed explicitly setting initial value (to 0
):
a = ["3"] = a.reduce { |sum, n| puts 'called'; sum + n.to_i } # no output p # => "3" = a.reduce(0) { |sum, n| puts 'called'; sum + n.to_i } # => called p # => 3
if want code reviewed, try code review stack exchange. biggest code smell definition of method inside method. use lambda or rid of instead.
Comments
Post a Comment