Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the differences between "each", "foreach", "collect" and "map"? [duplicate]

It seems like there are a lot of ways to loop over an Enumerable in Ruby. Are there any differences between each, foreach, or in collect, map or other similar methods?

Or is there a reason I shouldn't use certain methods in certain situations?

like image 940
Addison Avatar asked Jan 01 '26 08:01

Addison


2 Answers

collect/map are equivalent. They differ from each in that each only executes the block for each element, whereas collect/map return an array with the results of calling the block for each element. Another way to put it might be, each is expected to do something with each element, whereas map is expected to transform each element (map it onto something else).

You could use collect or map anywhere each is used, and your code will still work. But it will probably be slightly less efficient because it collects the results in an array, unless your Ruby implementation realizes it doesn't have to bother creating an array because it's never used.

Another reason to use each instead of map or collect is to help out anyone reading your code. If I see each then I can be like okay, we're about to use each element of the data to do something. If I see map then I'm expecting to see new data being created, based on a remapping of the old data.

With regards to map vs. collect I would say it's a matter of preference, but you should pick one and stick with it for consistency.

like image 188
miorel Avatar answered Jan 05 '26 04:01

miorel


Using pry and Rubinus (it's easier to read ruby code) take a look for yourself

$ pry
[1] pry(main)> cd Enumerable
[2] pry(Enumerable):1> show-method collect

From: .../rbx-head/kernel/common/enumerable18.rb @ line 4:
Owner: Enumerable
Visibility: public
Number of lines: 9

def collect
  if block_given?
    ary = []
    each { |o| ary << yield(o) }
    ary
  else
    to_a
  end
end

[3] pry(Enumerable):1> show-method map

From: .../rbx-head/kernel/common/enumerable18.rb @ line 4:
Owner: Enumerable
Visibility: public
Number of lines: 9

def collect
  if block_given?
    ary = []
    each { |o| ary << yield(o) }
    ary
  else
    to_a
  end
end
[4] pry(Enumerable):1>

So nope not for these two.

map and collect iterate over a collection. For each object it executes your block then collects the result. The each methods do not collect the results

like image 30
Paul.s Avatar answered Jan 05 '26 06:01

Paul.s



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!