kefahi
March 6, 2022, 1:04pm
1
Hello,
I’m puzzled with the outcome of this simple code.
The intention is to assign a unique number in each “cell”:
heirs = Array.new(2, Array.new(2, 0_i32))
(0..3).each { |i|
heirs[i//2][i%2] = i+1
}
p! heirs
This is the result I get (based on Crystal 1.3.2)
heirs # => [[3, 4], [3, 4]]
The expected outcome should have been:
heirs # => [[1, 2], [3, 4]]
Any clue on my wrong doing?
Thanks!
kefahi
March 6, 2022, 1:11pm
2
Update: My guess is that only one sub-array is created instead of two.
But, if so, how do I instruct crystal to create two sub-arrays?
hholst
March 6, 2022, 1:14pm
3
Why can’t this library support dense array notation like numpy? The representation of matrices as a list of lists is beyond inefficient it should be illegal.
Have a look at this instead if you want to work with real matrices
PS. This works right? It creates an Array of two (distinct) arrays. You’re only calling the .new method once in the inner section so there is just one inner Array - just as you already described.
heir = [[0,0],[0,0]]
(0..3).each { |i|
heirs[i//2][i%2] = i+1
}
1 Like
Update: My guess is that only one sub-array is created instead of two.
That’s exactly the reason. When you pass a value to Array.new(size, value)
, that value is used to initialize every position.
You can use the block version to use different values in every position. Try this:
heirs = Array.new(2) { Array.new(2, 0_i32) }
(0..3).each { |i|
heirs[i//2][i % 2] = i + 1
}
p! heirs
You can also use the block version to directly initialize the array with the values you need:
heirs = Array.new(2) do |i|
Array.new(2) do |j|
2*i + j + 1
end
end
p! heirs
3 Likes
kefahi
March 6, 2022, 1:44pm
6
Awesome!
The block version is concise and makes sense.
Thank you.