How to create an integer-for-loop in Ruby? - ruby

I have a variable "x" in my view. I need to display some code "x" number of times.
I basically want to set up a loop like this:
for i = 1 to x
do something on (i)
end
Is there a way to do this?

If you're doing this in your erb view (for Rails), be mindful of the <% and <%= differences. What you'd want is:
<% (1..x).each do |i| %>
Code to display using <%= stuff %> that you want to display
<% end %>
For plain Ruby, you can refer to: http://www.tutorialspoint.com/ruby/ruby_loops.htm

x.times do |i|
something(i+1)
end

for i in 0..max
puts "Value of local variable is #{i}"
end
All Ruby loops

You can perform a simple each loop on the range from 1 to `x´:
(1..x).each do |i|
#...
end

Try Below Simple Ruby Magics :)
(1..x).each { |n| puts n }
x.times { |n| puts n }
1.upto(x) { |n| print n }

Related

Why is my recursive function printing just once in my template?

I want to dynamically build similar components in my templates, so I created this recursive function in my page_view.ex:
defmodule MyProject.PageView do
use FabricaASA.Web, :view
defmodule Recursion do
def buildElements(element,n) when n <= 1 do
element
end
def buildElements(element, n) do
element
buildElements(element, n - 1)
end
end
end
Then, in my template I call it using:
<%= MyProject.PageView.Recursion.buildElements("LOL", 4) %>
The problem is that I'm getting just one LOL instead of 4 ...
The recursive version of buildElement has a "no operation" on the first line when you put element alone, resulting in just one item returned and the others lost. They should be collected together in an accumulator, e.g a list. Something like:
def buildElements(element,n) when n <= 1 do
[element] # EDIT: Must be a list too
end
def buildElements(element, n) do
[element | buildElements(element, n - 1)]
end
And even better (IMHO) than doing the formatting/concatenation of the list in the computation, you can iterate over it in the template.
<%= for element <- MyProject.PageView.Recursion.buildElements("LOL", 4) do %>
<%= element %>
<% end %>

call next on ruby loop from external method

in Ruby it's easy to tell loop to go to next item
(1..10).each do |a|
next if a.even?
puts a
end
result =>
1
3
5
7
9
but what if I need to call next from outside of the loop (e.g.: method)
def my_complex_method(item)
next if item.even? # this will obviously fail
end
(1..10).each do |a|
my_complex_method(a)
puts a
end
only solution I found and works is to use throw & catch like in SO question How to break outer cycle in Ruby?
def my_complex_method(item)
throw(:skip) if item.even?
end
(1..10).each do |a|
catch(:skip) do
my_complex_method(a)
puts a
end
end
My question is: anyone got any more niftier solution to do this ?? or is throw/catch only way to do this ??
Also what If I want to call my_complex_method not only as a part of that loop (=> don't throw :skip) , can I somehow tell my method it's called from a loop ?
You complex method could return a boolean, and then you compare on your loop like this:
def my_complex_method(item)
true if item.even?
end
(1..10).each do |a|
next if my_complex_method(a)
puts a
end
A simple approach, but different from the try catch one.
UPDATE
As item.even? already return a boolean value, you don't need the true if item.even? part, you can do as follow:
def my_complex_method(item)
item.even?
end
Enumerator#next and Enumerator#peek will be good option to goo :
def my_complex_method(e)
return if e.peek.even?
p e.peek
end
enum = (1..5).each
enum.size.times do |a|
my_complex_method(enum)
enum.next
end
Output
1
3
5
If all you need is to take actions on only some of values, based on value returned by my_complex_method you could use enumerators wisely:
(1..10).map { |a| [a, my_complex_method(a)] }.each do |a, success|
puts a if success
end
You could define method accepting block and take some action in this block based on success or failure there:
(1..10).each do |a|
my_complex_method { |success| next if success }
end
Thanks to scoping, you are able not to use `catch`/`throw`, and call `next` based on processing status.

Loop Controller for ".each do |x|" in ERB

I am trying to style the first element output through an object.each do |x| command by applying an .active class. I cannot figure it out though - how would I do that?
Use each_with_index(). Shown below in a non-ERB example for clarity.
['hello', 'world'].each_with_index do |item, index|
if index == 0
puts "This is the first item"
end
puts item
end
Prints out:
This is the first item
hello
world
It seems very obvious:
objects.first.css_options += ' .active'
And then iterate through all objects in usual manner.
In case of variation can be different, for example you want also apply css option to last element:
objects.zip(['active','','',...]).each do |obj,klass|
obj.css_option += klass
...
end
[obj1, obj2].each_with_index do |item, index|
item.css_option += ' .active' if index == 0
end

#things.each or 5.times do |t|

Is there a way to have an iterator that iterates anyways even when the object is nil?
For example, I'd like to strip my views from my application and create a dummy app for a designer.
So I would like it to iterate or loop.
How can this be done?
I've just found a way of doing it
<%
(#messages.count == 0 ? Array.new(5).map { Message.new } : #messages.each).each do |m|
%>
You should be able to use something like this:
(#things || dummy_things).each do |thing|
# do something with thing
end
def dummy_things
dummies = []
5.times do
dummies.push(Thing.new)
end
dummies
end
So what this does is to iterarte over dummy things if #things was nil, otherwise only iterate over #things.
EDIT
A more concise version of dummy_things, as mentioned by Victor, would be something like this:
def dummy_things
(0..4).map{ Thing.new }
end
Answer is in your question only, even if you don't have any object, you can iterate 5 times using
5.times do |i|
puts "Dummy page"
end

Ruby passing blocks to blocks

(1..5).each do|x| puts yield(x) end do |x| return x*2 end
In my head this would loop 1 through 5 call the first block that would yield to the second block and put 2,4,6,8,10
Why does this not work and whats the easiest way to write this.
yield works within the methods. Quote from "Programming Ruby":
Within the method, the block may be invoked, almost as if it were a
method itself, using the yield statement.
So, if you want to make this code working, you can change it to something like this:
def f(n)
(1..n).each do |x|
puts yield(x)
end
end
f(5) do |x|
x * 2
end
If you don't want to define method you should put block into the variable and then use it:
b = Proc.new{|x| x *2 }
(1..5).each do |x|
puts b.call(x)
end
The easiest way to write this:
(1..5).each { |x| puts x*2 }

Resources