59

I want to fill an array with 1 element but 5 times. What I got so far.

number = 1234
a = []

5.times { a << number }
puts a # => 1234, 1234, 1234, 1234, 1234

It works but this feels not the ruby way. Can someone point me in the right direction to init an array with 5 times the same value?

Sagar Ranglani
  • 5,491
  • 4
  • 34
  • 47
AME
  • 2,262
  • 6
  • 19
  • 39

5 Answers5

98

For immutable objects like Fixnums etc

Array.new(5, 1234) # Assigns the given instance to each item
# => [1234, 1234, 1234, 1234, 1234]

For Mutable objects like String Arrays

Array.new(5) { "Lorem" } # Calls block for each item
# => ["Lorem", "Lorem", "Lorem", "Lorem", "Lorem"]
Christopher Oezbek
  • 23,994
  • 6
  • 61
  • 85
sawa
  • 165,429
  • 45
  • 277
  • 381
  • 24
    This is the correct solution for immutable objects (Fixnums, Symbols, etc.) but for mutable objects (Strings, Arrays, etc.) you will get an Array with 5 pointers to the _same object_, which is probably not what you want. In that case use the block form `Array.new(5) { "foo" }`. – Max Jun 26 '14 at 15:26
39

This should work:

[1234] * 5
# => [1234, 1234, 1234, 1234, 1234]
Marek Lipka
  • 50,622
  • 7
  • 87
  • 91
26

Although the accepted answer is fine in the case of strings and other immutable objects, I think it's worth expanding on Max's comment about mutable objects.

The following will fill an array of elements with 3 individually instantiated hashes:

different_hashes = Array.new(3) { {} } # => [{}, {}, {}]

The following will fill an array of elements with a reference to the same hash 3 times:

same_hash = Array.new(3, {}) # => [{}, {}, {}]

If you modify the first element of different_hashes:

different_hashes.first[:hello] = "world"

Only the first element will be modified.

different_hashes # => [{ hello: "world" }, {}, {}]

On the other hand, if you modify the first element of same_hash, all three elements will be modified:

same_hash.first[:hello] = "world"
same_hash # => [{ hello: "world" }, { hello: "world" }, { hello: "world" }]

which is probably not the intended result.

hjing
  • 4,922
  • 1
  • 26
  • 29
4

You can fill the array like this:

a = []
=> []

a.fill("_", 0..5) # Set given range to given instance
=> ["_", "_", "_", "_", "_"]

a.fill(0..5) { "-" } # Call block 5 times
Christopher Oezbek
  • 23,994
  • 6
  • 61
  • 85
Alexander Luna
  • 5,261
  • 4
  • 30
  • 36
  • 1
    This can be done in one step with `Array.new(6) {"_"}`. Also, I can't submit an edit this small, but the number of elements in the example output should be 6, not 5. – Tyler James Young Oct 07 '19 at 04:12
0

these two methods will give an array of N values in ruby

Array.new(5, 2) => [2,2,2,2,2]

[2] * 5 => [2,2,2,2,2]