How does ruby works with array of arrays [closed] - ruby

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am facing something i do not fully understand.
I have an array whose elements are arrays.
So I have two nested loops, in the inner loop I fill my inner array
then in the outer loop i fill the outer array with the inner array.
arr=[]
mat=[]
for m in (0..1)
for k in (0..1)
arr[k]=rand.to_s
end
mat[m]=arr
end
At the end my matrix is filled with two array; each array contains the values calculated in the last iteration.
If i want the first element in matrix to contain the first computed array I have to reinitialize the arr object at each loop.
So it seems that assignment is made by reference until the arr object is "cleaned". If I add
mat[m]=arr
arr=[]
all works as expected: mat[0] will contain the array computed in the first loop, and mat[1] will contain the array computed in the second loop.
Is this by design or is it an undesired side effect?
This is happening only if I assign arrays as array elements. If if fill an array with simple string variables in a loop all goes as expected.
I know that it is good programming practice to avoid reusing objects, but this behavior is anyway strange.

Your problem is that your arr variable's contents is being overwritten with each iteration: the arr[k] overwrites whatever is in there already. The arr variable needs to be local to the block instead:
mat = []
2.times do # avoid for... use iterators instead
row = []
2.times do
row << rand.to_s
end
mat << row
end

I like the approach of using hashes instead of multidimensional arrays.
How about this:
def creat­e_matrix x, y, conte­nt = nil, &block
rows = (0...x­).to_a
cols = (0...y­).to_a
indices = rows.­product cols
matrix = {}
indices.ea­ch { |inde­x| matri­x[index] = ( block­_given? ? yield­( index ) : conte­nt ) }
matrix
end
Then do:
matrix = create_matrix( 2, 2 ) { rand.to_s }
You will get a hash, that you can access like this:
matrix[[0, 1]] #note the double brackets

Another way of doing it:
(1..4).map{rand}.each_slice(2).to_a

Related

How do i print a string with repeated names followed by a number - Ruby? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
How do i print a name Ex. John1 and then print after John2, john3, john4, john5 and so one in an infinite number
I started using ruby today and I'm having some trouble figuring this out. I've searched some but can't find anything so how would I do this?
It's to mass produce accounts to the staff of a certain company and I found ruby to be the smartest to write it in and I will never use it again after this
Keep it simple.
puts (1..5).map { |n| "john#{n}" }
john1
john2
john3
john4
john5
The class Range includes the module Enumerable (as does the classes Array, Hash and others). By doing so, instances of Range (such as 1..5) gain the use of all of Enumerable's instance methods. One of Enumerable's instance methods is used here: Enumerable#map.
For printing a simple series like this:
n = 1
loop do
print 'john%d, ' % n
n += 1
end
That will never terminate, which makes it kind of silly. Maybe what you want is a bounded range:
list = (1..10).map do |n|
'john%d' % n
end.join(', ')
puts list
You can adjust the start and end values as necessary.
Perhaps use an enumerator here:
enum = Enumerator.new do |y|
i = 1
loop do
y << "John#{i}"
i += 1
end
end
enum.next #=> "John1"
enum.next #=> "John2"
enum.next #=> "John3"
Then use any one of the methods available to instances of Enumerator. Here we've used Enumerator#next to get the next "John" string.
One simple way is using a for loop. First declare an empty string variable that will hold our contents.
One important thing to consider is the index of the loop. If it's the last item, we do not want to add a separator like ", "
This is where the conditional comes into play. If the index is less than the last, we will add a comma and space, otherwise just the name.
Interpolation is done by wrapping a variable inside #{ and }
str = ""
for i in 1..5
str += i < 5 ? "john#{i}, " : "john#{i}"
end
Returns
"john1, john2, john3, john4, john5"

Ruby change value in two dimensional array

I want to change a value of a two dimensional array.
This is the array:
class Test
def initialize
#single = [1,2,3,4,5,6,7,8,9,10]
#double = [#single, #single, #single, #single]
end
def changeValue i, j
#double[i][j] = nil
end
def showDouble
return #double
end
end
I want to change a value in the double array (the two dimensional array). If I want to change the value of 9 in the first array, then I should do something like this:
test = Test.new
test.changeValue 0, 8
puts test.showDouble
When I do this, then the value of 9 is in every array nil. I only want to change it in one array. Any help is welcome! :)
The array #double actually contains four references to the same array #single, which is why you're getting the behavior you describe.
Initialize #double = [#single.clone, #single.clone, #single.clone, #single.clone] to get independent (but initially identical) sub-arrays.
Here
#double = [#single, #single, #single, #single]
you fill array with same object, in changeValue you change it, so it is being changed 4 times for #double. If you want 4 different objects, init #double as:
#double = [#single.dup, #single.dup, #single.dup, #single.dup]

Ruby array access position in array

#product
returns a single record. By relationship this product belongs to a slot
#slot = Slot.where(['id = ?', #product.slot_id]).first
what needs to be accessed is the position x in the array of all #slots = Slot.order('id asc').all so that I can identify or iterate over the following n slots as per ruby array Class:
arr[x, n]
I am not sure I understand the question there are many methods of accessing the index for an Array e.g.
alphabet = ('a'..'z').to_a
alphabet[0]
#=> "a"
alphabet.values_at(2,3,12)
#=> ["c","d","m"]
alphabet.index('r')
#=> 17
alphabet.fetch(15)
#=> "p"
There are many more such as #at, #find_index, even #rindex which will look for the last occurance. If you need to iterate index's you can use each_index or each_with_index. Since your question does not truely explain the scenario all I can do is explain how to deal with Array indices. For a more pertinent answer please update your question to show both data and expected results.
Here is what I can gather from your question
#product = Product.find(some_id)
#slot = #product.slot
#slots = Slot.where("id > ?", #slot.id) #return all slots after the #product.slot
If want to get the Slot for a given Product you can just do this:
slot = #product.slot
assuming you have your relationships well defined.

What does `each` method return? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
When I call
#data.each do |d|
some code here
end
what does the each method return? An array of objects? Or more generally, what does do...end block take?
It iterates over the members of the enumerable object. So if #data is an array it will return the elements of the array one at a time as d. Exact behavior depends on the type of object. See the docs
Books.all returns a object, that although it is not an array, behaves like one in this case.
each returns the receiver, in this case #data.
The do ... end is a block.
The each method will run the block (using the method yield) once for each value in data. This is called an iterator. For an array it will iterate over all the values in the array, for a hash it will run once per every pair of (key,value). You can define your own iterator for your own classes.
The return value of each depends on the object it is invoked. When invoked on an array it will return the array.
In your case the method each will execute the block once per each value and send each value as a parameter to the block.
For example-
a = [1,2,3]
a.each do |n|
p n
end
is just the same as
p a[0]
p a[1]
p a[2]

Problems with loops in Ruby Code [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Hey I have an array with numbers in it.
Now I want to divide the value at 17th position of the array by the value at the first position of the array, then the 18th by the second, and so on. The results should build a new array.
Then I want to scan all values of the new array and if two or more successive values are bigger than 1.2, I want to add the result of dividing the first by the last value of that row for all of successive values. If one value is 1.2 and the next for example 0.8, the values of the array should not be changed.
Here is my code:
a = [1,2,3,4,5,9,5,13,14,17,19,23,19,34,46,12,13,45,46,67,78,79]
b = Array.new
c = Array.new
a.each_cons(18) { |c| b.push(c[17]/c[0] }
Do you have an idea how to implement the condition?
I think this will do it, although I selectively interpreted some things from your question. Specifically, in "of that row for all of successive values," does "row" refer to the sliding block from each_cons? Ditto for "all of successive values."
catch (:done) do
for i in 2..b.length do
b.each_cons(i) do |d|
for j in 2..d.length do
d.each_cons(j) do |g|
if g.all? { |g| g > 1.2 }
c = b.map { |f| f + (d[0].to_f/d[i-1].to_f) }
break
end
if !c.empty? then throw :done end
end
end
end
end
end
puts c

Resources