Reputation: 11
I'm confused about this codethat didn't work for me.
tab=Array.new
tab<<"1,2,3"
tab<<"4"
tab<<"5,6"
x=tab.inject([]){|t,elt|
if elt.include?(',')
s=elt.split(',')
s.each{|y| t<<y}
else
t<<elt
end
}
STDOUT.puts x
============= outpout:5 6 but if i change the code,
tab=Array.new
tab<<"1,2,3"
tab<<"4"
tab<<"5,6"
x=tab.inject([]){|t,elt|
if elt.include?(',')
s=elt.split(',')
s.each{|y| t<<y}
else
t<<elt
end
t.each{|tt| tt} #i add this line
}
STDOUT.puts x
======output: 1 2 3 4 5 6 does anyone has an explanation? thx
Upvotes: 0
Views: 453
Reputation: 118261
In your #inject
block, you passed last entry as "5,6"
. Now inside the if
block, you splitted it to an array. Then you called the method #each
on [5,6]
. Now #each
method returns the receiver on which you called it.
But in the second case, you called t.each
at the last of each iteration of the inject
block. So on the final pass t
is a complete array [1,2,3,4,5,6]
. Now as I said, Array#each
returns the receiver, so you got the full t
back , that [1,2,3,4,5,6]
.
I would write your code as :
ary = ["1,2,3","4","5,6"]
ary.flat_map { |str| str.include?(",") ? str.split(',') : str }
# => ["1", "2", "3", "4", "5", "6"]
If you want to use #inject
do :
ary = ["1,2,3","4","5,6"]
ary.inject([]) { |a,str| a.concat(str.split(',')) }
# => ["1", "2", "3", "4", "5", "6"]
Upvotes: 1
Reputation: 239240
With inject
, the return value from each block is passed to the subsequent block. Your first example, the return value is the value of s.each{|y| t<<y}
; the final iteration will return [5, 6]
. Your second example indirectly returns t
; t.each { }
returns t
so that additional methods can be chained to it.
You need to return the collection you're building up at the end of each block:
x=tab.inject([]){|t,elt|
if elt.include?(',')
s=elt.split(',')
s.each{|y| t << y}
else
t<<elt
end
t
}
You can make this significantly smaller however; just add the new element(s) to the existing elements, and return the result:
tab.inject([]) { |t, elt|
t + elt.include?(',') ? elt.split(',') : Array[elt]
}
Upvotes: 0