It is a bit difficult for me to understand the difference between map and each, until I found out this in irb accidentally,
irb(main):001:0> name = %w{guido knuth adrian dhh pg} => ["guido", "knuth", "adrian", "dhh", "pg"] irb(main):002:0> name.each {|n| n.upcase} => ["guido", "knuth", "adrian", "dhh", "pg"] irb(main):003:0> name.map {|n| n.upcase} => ["GUIDO", "KNUTH", "ADRIAN", "DHH", "PG"] |
map and each are suppose to do almost the same thing, but why each didn’t return the correct result in uppercase like what map did?
The different is each yield each element in the collection to the code block, in this case perform the upcase method, but return the receiver, which is the original array, hence an array of lower case names.
Whereas, map return a new array, consists of elements already went through the code block, hence an array of upper case names.
irb(main):007:0> name.each {|n| p n.upcase} "GUIDO" "KNUTH" "ADRIAN" "DHH" "PG" => ["guido", "knuth", "adrian", "dhh", "pg"] irb(main):006:0> name.map {|n| p n.upcase} "GUIDO" "KNUTH" "ADRIAN" "DHH" "PG" => [nil, nil, nil, nil, nil] |
So here you can see with p, both map and each output the uppercase names, but look more carefully, the return value of each, as expected, is the original array. map however, return an array of nils!
Why is that?
Anton
Because, “each” does not change the object to be used.
But the “map” changes. Since the method of “p” always returns nil, name.map (| n | p n.upcase) return [nil, nil, nil, nil, nil]
kahfei
Hi Anton, thanks, silly me, of course p always return nil,
Now, I get the nils array for map part. But why p didn’t return the nil array for each? Is it because of the binding to each, which return the receiver is stronger then the binding to p, which should return nil?
Anton
Hi!
Sorry, i don`t understand your question.
Why name.map {|n| p n.upcase} return array of nils?
Because map change every element in the array to the value given in the block.
P.S. Sorry for my bad english, i from Russia 🙂
kahfei
Hi Anton,
No problem, English is not my mother tongue as well, 🙂
Actually my question is why “p” return nil for “map” but not for “each”.
Then, I read again your comment, now I can see why.
“map” return a new array consist of elements processed by the code block, hence all the “nils” from “p”.
“each” return the receiver of the code block, which is always the original array, [“guido”, “knuth”, “adrian”, “dhh”, “pg”].
Hey, thanks again, Anton.
Anton
Yes!
No problem, let me know if you have questions 🙂
Deswing666
it was very interesting to read http://www.kahfei.com
I want to quote your post in my blog. It can?
And you et an account on Twitter?
kahfei
Deswing, sure, if my post did bring any help in anyway, you are free to quote it :-).