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:
- Creation of enumerator for range object (2..20)
- 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
Bundle Install Fails With Ssl Certificate Verification Error
Connecting Rails 3.1 With Multiple Databases
Ruby Multiline Block Without Do End
Rails Keeps Telling Me That It's Not Currently Installed
Difference Between Ruby 1.8 and Ruby 1.9
How to Check If a Url Is Valid
Sqlite3-Ruby Install Error on Ubuntu
Difference Between Stdin and $Stdin in Ruby
How to Reload the Current Page in Ruby on Rails
What Is Ruby'S Double-Colon '::'
How to Create Multiple Submit Buttons For the Same Form in Rails
Nokogiri Installation Fails -Libxml2 Is Missing
Is There a Performance Gain in Using Single Quotes VS Double Quotes in Ruby