"For" VS "Each" in Ruby

for vs each in Ruby

This is the only difference:

each:

irb> [1,2,3].each { |x| }
=> [1, 2, 3]
irb> x
NameError: undefined local variable or method `x' for main:Object
from (irb):2
from :0

for:

irb> for x in [1,2,3]; end
=> [1, 2, 3]
irb> x
=> 3

With the for loop, the iterator variable still lives after the block is done. With the each loop, it doesn't, unless it was already defined as a local variable before the loop started.

Other than that, for is just syntax sugar for the each method.

When @collection is nil both loops throw an exception:

Exception: undefined local variable or method `@collection' for main:Object

Difference between 'for' and 'each' Iterators on Ruby on Rails

Surprisingly the for construct in Ruby is hardly ever used. People tend to prefer the each style iterator or one of its friends like each_with_index or each_with_object as those are significantly more versatile and often perform better.

I'd strongly recommend you use the each method unless you have a very compelling reason.

The differences are somewhat academic, but the big advantage of using each is you're actually interacting with an iterator and you have a lot of ways of using that. You can actually pass through an iterator from one method to another, and you can chain them together to set up the right structure before doing any work.

The real meat here is inside Enumerable where each is the most basic version of this kind of iterator. There are many that are often a much better fit for whatever problem you're trying to solve.

So, yes, for and each are basically the same, but each is better because it's got friends.

Difference between &.each and .each for arrays in ruby?

&.each is an operator and a method. each is only one method.

&., called “safe navigation operator”, allows to skip method call when
receiver is nil. It returns nil and doesn't evaluate method's
arguments if the call is skipped.

So, if the receiver is nil (which isn't the case in your example) it'll just return nil because it doesn't respond to each:

nil&.each
# nil

Otherwise, invoking any non-defined method in an object throws a NoMethodError. And is what you'll get in your second example:

nil.each
# ...
# NoMethodError (undefined method `each' for nil:NilClass)

The documentation about the safe navigation operator is in the Calling Methods documentation. While for each it's in Array.

Ruby: What is the difference between a for loop and an each loop?

There is a subtle difference regarding scoping, but I would recommend understanding it well as it reveals some of important aspects of Ruby.

for is a syntax construct, somewhat similar to if. Whatever you define in for block, will remain defined after for as well:

sites = %w[stackoverflow stackexchange serverfault]
#=> ["stackoverflow", "stackexchange", "serverfault"]

for x in sites do
puts x
end
stackoverflow
stackexchange
serverfault
#=> ["stackoverflow", "stackexchange", "serverfault"]
x
#=> "serverfault"

On the other hand, each is a method which receives a block. Block introduces new lexical scope, so whatever variable you introduce in it, will not be there after the method finishes:

sites.each do |y|
puts y
end
stackoverflow
stackexchange
serverfault
#=> ["stackoverflow", "stackexchange", "serverfault"]
y
NameError: undefined local variable or method `y' for #<Object:0x855f28 @hhh="hello">
from (irb):9
from /usr/bin/irb:12:in `<main>'

I would recommend forgetting about for completely, as using each is idiomatic in Ruby for traversing enumerables. It also recspects the paradigm of functional programming better, by decreasing chances of side-effects.

difference between each .. do or for .. in loops in rails

They are different (although it may not matter for your purposes).

for doesn't create a new scope:

blah = %w(foo bar baz)
for x in blah do
z = x
end
puts z # "baz"
puts x # "baz"

.each creates a new scope for the block:

blah.each { |y| a = y }
puts a # NameError
puts y # NameError

Ruby each vs while loop performance

It seems the cost is added by:

  1. Creation of enumerator for range object (2..20)
  2. Invocation of block in the each

Here is a benchmark

require 'benchmark'

c = 100_000
Benchmark.bm(7) do |x|
x.report("range - 1 :") { c.times { (2..20) } }
x.report("range - 2 :") { c.times { (2..20).each } }
x.report("range - 3 :") { c.times { (2..20).each { |x| x } } }
end

Sample output of above is:

              user     system      total        real
range - 1 : 0.000000 0.000000 0.000000 ( 0.006004)
range - 2 : 0.031000 0.000000 0.031000 ( 0.026017)
range - 3 : 0.125000 0.000000 0.125000 ( 0.122081)
[Finished in 0.4s]

As can be seen, creation of Range object is not a problem, but creating an enumerator for it adds time, and passing a block to that iterator and executing some code, adds further cost.

Compared to this, the while loop implementation is doing primitive operations. Hence, is faster.

Please note that for loop will perform as badly as each, as it is more or less equivalent to each implementation

What are the differences between each, foreach, collect and map?

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.

Ruby: using `.each` or `.step`, step forward a random amount for each iteration

Get a random value for the number of elements to pick, randomly get this number of elements, sort.

(0..99).to_a.sample((0..99).to_a.sample).sort
#⇒ [7, 20, 22, 29, 45, 48, 57, 61, 62, 76, 80, 82]

Or, shorter (credits to @Stefan):

(0..99).to_a.sample(rand(0..99)).sort
#⇒ [7, 20, 22, 29, 45, 48, 57, 61, 62, 76, 80, 82]

Or, in more functional manner:

λ = (0..99).to_a.method(:sample)
λ.(λ.()).sort

To feed exactly N numbers:

N = 10
(0..99).to_a.sample(N).sort
#⇒ [1, 5, 8, 12, 45, 54, 60, 65, 71, 91]

Array#each vs. Array#map

Array#each executes the given block for each element of the array, then returns the array itself.

Array#map also executes the given block for each element of the array, but returns a new array whose values are the return values of each iteration of the block.

Example: assume you have an array defined thusly:

arr = ["tokyo", "london", "rio"]

Then try executing each:

arr.each { |element| element.capitalize }
# => ["tokyo", "london", "rio"]

Note the return value is simply the same array. The code inside the each block gets executed, but the calculated values are not returned; and as the code has no side effects, this example performs no useful work.

In contrast, calling the array's map method returns a new array whose elements are the return values of each round of executing the map block:

arr.map { |element| element.capitalize }
# => ["Tokyo", "London", "Rio"]


Related Topics



Leave a reply



Submit