0

I couldn't find a way to build an array such as

[  [1,2,3] , [1,2,3] , [1,2,3] , [1,2,3] , [1,2,3]  ]

given [1,2,3] and the number 5. I guess there are some kind of operators on arrays, such as product of mult, but none in the doc does it. Please tell me. I missed something very simple.

2 Answers 2

8

Array.new(5, [1, 2, 3]) or Array.new(5) { [1, 2, 3] }

Array.new(size, default_object) creates an array with an initial size, filled with the default object you specify. Keep in mind that if you mutate any of the nested arrays, you'll mutate all of them, since each element is a reference to the same object.

array = Array.new(5, [1, 2, 3])
array.first << 4
array # => [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]

Array.new(size) { default_object } lets you create an array with separate objects.

array = Array.new(5) { [1, 2, 3] }
array.first << 4
array #=> [[1, 2, 3, 4], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]] 

Look up at the very top of the page you linked to, under the section entitled "Creating Arrays" for some more ways to create arrays.

Sign up to request clarification or add additional context in comments.

2 Comments

Hum, totally missed this... Thanks ! :)
I don't often look at the top of the doc pages, either. Count it as a lesson learned for both of us :)
4

Why not just use:

[[1, 2, 3]] * 5 
# => [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]

The documentation for Array.* says:

...returns a new array built by concatenating the int copies of self.

Typically we'd want to create a repeating single-level array:

[1, 2, 3] * 2 
# => [1, 2, 3, 1, 2, 3]

but there's nothing to say we can't use a sub-array like I did above.


It looks like mutating one of the subarrays mutates all of them, but that may be what someone wants.

It's like Array.new(5, [1,2,3]):

foo = [[1, 2, 3]] * 2
foo[0][0] = 4
foo # => [[4, 2, 3], [4, 2, 3]]

foo = Array.new(2, [1,2,3])
foo[0][0] = 4
foo # => [[4, 2, 3], [4, 2, 3]]

A work-around, if that's not the behavior wanted is:

foo = ([[1, 2, 3]] * 2).map { |a| [*a] }
foo[0][0] = 4
foo # => [[4, 2, 3], [1, 2, 3]]

But, at that point it's not as convenient, so I'd use the default Array.new(n) {…} behavior.

1 Comment

I like this approach, too. It looks like mutating one of the subarrays mutates all of them, but that may be what someone wants.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.