Why is my recursive function printing just once in my template? - phoenix-framework

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 %>

Related

How does form_for generate paths in rails?

Can anyone explain me on how the paths are generated using form_for?. The below code generates a path article_comments_path.
<%= form_for [#article, #comment] do |f| %>
<% end %>
I mean how does it exactly generate article_comments_path and not articles_comment_path
It is using polymorphic_path method to determine the path. It is basicaly a wrpaper around polymorphic_url: http://apidock.com/rails/v4.0.2/ActionDispatch/Routing/PolymorphicRoutes/polymorphic_url
Update:
polymorphic_path is using internally method called build_named_route_call. When it gets an array, it pull the last record out of the array (with pop) and then iterates over the remaining array, changing all the objects to
if it is a model it takes it class and calls `model_name.singular_route_key'
if it is a symbol or string, leaves it as it is
Then we are left with the last element. It can be singular or plural, this is resolved in polymorphic_url method with this case statement:
inflection = if options[:action] && options[:action].to_s == "new"
args.pop
:singular
elsif (record.respond_to?(:persisted?) && !record.persisted?)
args.pop
:plural
elsif record.is_a?(Class)
args.pop
:plural
else
:singular
end
where record is a first element of the array (if array is passed). inlection var is then passed to build_named_route_call so it can build correct helper name. As you can see this form will generate different paths depending on whether the first element is already persisted or not.

Repeat an iteration of an array in ruby

Consider I have a loop with a conditional inside, if the condition is true then the current iteration of the loop has to be repeated. For example, consider the following method. Read the note inside the if statement.
def func1(arr)
size = arr.size - 1
max = arr[size]
0.upto(size) do |x|
if (*boolean statement*)
*repeat current iteration*
end
end
func2(arr)
end
How would I go about doing this? In case you are wondering why I need this is because I'm modifying the array such that if the conditional is true for a given x, then the element at index x is removed and placed at the end of the array. If the loop continues then it skips the element after x because this one now has the index of the one removed. In java this is done with the continue keyword I think, is there a ruby equivalent?
Thanks!
Use redo:
def func1(arr)
size = arr.size - 1
max = arr[size]
0.upto(size) do |x|
redo if (*boolean statement*)
end
func2(arr)
end
If I understand your question it seems you simply
need to replace your 'if' conditional with a 'while' one:
def func1(arr)
size = arr.size - 1
max = arr[size]
0.upto(size) do |x|
while (*boolean statement*)
*repeat current iteration*
end
end
func2(arr)
end

Ruby: showing one subarray per page

I am using Ruby (+ Sinatra) to work on one of my web projects.
I have an array with quite a bit of content and only want to display 10 of the array elements per page.
So what I did so far is:
creating an array with all of the content
ary = ["ex1", "ex2", "ex3", … ,"ex60" ] // all elements
splitting the array into subarrays
ary.each_slice(10).to_a // subarrays with fewer content
Now, I need a way to split the subarrays into single arrays and give them a name,
for example:
#subAry1 # ex1, ex2, ex3, … ex10
#subAry2 # ex11, ex12, ex13, … ex20
#subAry3 # ex21, ex22, ex23, … ex30
I stuck on creating these arrays with a continuing number in the array name.
When I would have my arrays split, I would use this in my .erb file:
<% currentAry = #subAry1 %>
<% currentAry.each do |element| %><%= element %><% end %>
and this to change the content, if the "next" button gets pressed:
currentAry = #subAry + '1'
Can somebody help me, or is it even an effective way, to split/display array elments on my page?
How about an array of arrays? Here's something to help you get started.
all = ary.each_slice(10).to_a
current_page = 0
In the ERB file:
<% all[current_page].each do |element| %><%= element %><% end %>
and after the "next" button gets pressed
current_page += 1

How to create an integer-for-loop in 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 }

Syntax for a for loop in ruby

How do I do this type of for loop in Ruby?
for(int i=0; i<array.length; i++) {
}
array.each do |element|
element.do_stuff
end
or
for element in array do
element.do_stuff
end
If you need index, you can use this:
array.each_with_index do |element,index|
element.do_stuff(index)
end
limit = array.length;
for counter in 0..limit
--- make some actions ---
end
the other way to do that is the following
3.times do |n|
puts n;
end
thats will print 0, 1, 2, so could be used like array iterator also
Think that variant better fit to the author's needs
I keep hitting this as a top link for google "ruby for loop", so I wanted to add a solution for loops where the step wasn't simply '1'. For these cases, you can use the 'step' method that exists on Numerics and Date objects. I think this is a close approximation for a 'for' loop.
start = Date.new(2013,06,30)
stop = Date.new(2011,06,30)
# step back in time over two years, one week at a time
start.step(stop, -7).each do |d|
puts d
end
The equivalence would be
for i in (0...array.size)
end
or
(0...array.size).each do |i|
end
or
i = 0
while i < array.size do
array[i]
i = i + 1 # where you may freely set i to any value
end
array.each_index do |i|
...
end
It's not very Rubyish, but it's the best way to do the for loop from question in Ruby
To iterate a loop a fixed number of times, try:
n.times do
#Something to be done n times
end
If you don't need to access your array, (just a simple for loop) you can use upto or each :
Upto:
2.upto(4) {|i| puts i}
2
3
4
Each:
(2..4).each {|i| puts i}
2
3
4
What? From 2010 and nobody mentioned Ruby has a fine for /in loop (it's just nobody uses it):
ar = [1,2,3,4,5,6]
for item in ar
puts item
end
['foo', 'bar', 'baz'].each_with_index {|j, i| puts "#{i} #{j}"}
Ruby's enumeration loop syntax is different:
collection.each do |item|
...
end
This reads as "a call to the 'each' method of the array object instance 'collection' that takes block with 'blockargument' as argument". The block syntax in Ruby is 'do ... end' or '{ ... }' for single line statements.
The block argument '|item|' is optional but if provided, the first argument automatically represents the looped enumerated item.

Resources