Forum: Ruby Setting values of multidimensional arrays

D746399278f145e0a2afcc55ae725e96?d=identicon&s=25 Very Newbe (verynewbe)
on 2014-04-22 21:44
Hi!

I have a problem where I have to set values in a multidimensional array
with a range of dimensions.

My function gets two arguments. First the array to set, and second an
array with indexes.

Lets say indexes are [1,2,3,4,5] and the name of the array is "arr". I
then want to set the value of arr[1][2][3][4][5]. How can I achive this?

I was thinking about a loop with pointers/references but that doesn't
seem to exist in ruby? Are there other solutions?
14b5582046b4e7b24ab69b7886a35868?d=identicon&s=25 Joel Pearson (virtuoso)
on 2014-04-22 23:30
You can assign the array to variable, and then hand that variable to
each step in the loop. The loop goes through the indices and updates the
variable, drilling down progressively through the layers.
By using an "each" loop, you don't need to know how deep the array goes.
You can then handle as many layers as necessary.

a = Array.new(8) { Array.new(8) { Array.new(8) { Array.new(8) {
Array.new(8,1) } } } }

a[1][2][3][4][5] = 2

def test( array, indices )
  indices.each { |idx| array = array[idx] }
  array
end

test a, [1,2,3,4,5]
=> 2
D746399278f145e0a2afcc55ae725e96?d=identicon&s=25 Very Newbe (verynewbe)
on 2014-04-23 00:07
I'm sorry if I didn't make myself very clear in my first post but while
that works great for retrieving the value of the multidimensional array,
my problem is setting the value.

Like

a = Array.new(8) { Array.new(8) { Array.new(8) { Array.new(8) {
Array.new(8,1) } } } }

a[1][2][3][4][5] = 2

def test( array, indices )
  #Something equivalent of array[1][2][3][4][5] = 10
end

test a, [1,2,3,4,5] => #Modified array
A4a7280005cf9ff33e12ef922fb75a7e?d=identicon&s=25 Wender J. (wender_j)
on 2014-04-23 02:59
Sorry if I didn't understand well but maybe you can make two loops.

something like this

a = Array.new(8) { ... }
indexes = [1,2,3,4,5]

a.each do
  indexes.each do |i|
    ar[i] = ...
  end
end

for each index read you set that right position of array with some value
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2014-04-23 13:05
Very Newbe wrote in post #1143808:
> I'm sorry if I didn't make myself very clear in my first post but while
> that works great for retrieving the value of the multidimensional array,
> my problem is setting the value.
>
> Like
>
> a = Array.new(8) { Array.new(8) { Array.new(8) { Array.new(8) {
> Array.new(8,1) } } } }
>
> a[1][2][3][4][5] = 2
>
> def test( array, indices )

It seems there is an argument missing for the new value.

>   #Something equivalent of array[1][2][3][4][5] = 10
> end
>
> test a, [1,2,3,4,5] => #Modified array

like

def update(array, indices, value)
  (indices[0...-1].inject(array) {|a,i| a[i]})[indices.last] = value
end

?

Cheers

robert
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2014-04-23 13:06
Wender J. wrote in post #1143810:
> Sorry if I didn't understand well but maybe you can make two loops.
>
> something like this
>
> a = Array.new(8) { ... }
> indexes = [1,2,3,4,5]
>
> a.each do

There is absolutely no point in the line above.  Iterating the root
Array does not make sense.

>   indexes.each do |i|
>     ar[i] = ...
>   end
> end
>
> for each index read you set that right position of array with some value

Cheers

robert
D746399278f145e0a2afcc55ae725e96?d=identicon&s=25 Very Newbe (verynewbe)
on 2014-04-23 13:10
Robert Klemme wrote in post #1143822:
> It seems there is an argument missing for the new value.
>
>
> like
>
> def update(array, indices, value)
>   (indices[0...-1].inject(array) {|a,i| a[i]})[indices.last] = value
> end
>
> ?
>
> Cheers
>
> robert
Exactly! Wow that was a really neat solution, got to love ruby. :)

Thanks a lot for the replies
14b5582046b4e7b24ab69b7886a35868?d=identicon&s=25 Joel Pearson (virtuoso)
on 2014-04-24 23:45
Robert Klemme wrote in post #1143822:
> def update(array, indices, value)
>   (indices[0...-1].inject(array) {|a,i| a[i]})[indices.last] = value
> end

Dammit... I live for the day when I can offer solutions as elegant as
Robert's!
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.