Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expand array with preferred default

The documentation for Array#[]= notes that

If indices are greater than the current capacity of the array, the array grows automatically.

When it does grow automatically, it does so with nil values:

arr = []
arr[2] = "!"
arr # => [nil, nil, "!"]

Is it possible to specify what the default is for those first two values?

Currently, I'm doing

arr = []
index = 2
currently_uninitialized_value_range = (arr.length)...(index)
default_values = currently_uninitialized_value_range.map{ "" }
arr[currently_uninitialized_value_range] = default_values
arr[index] = "!"
arr # => ["", "", "!"]

Which is a little verbose.

I'm using an array, rather than a hash, because they're representing the values I'm going to be inputting into a spreadsheet, and the library I'm using (Axlsx) prefers to have data added row by row.

like image 586
Andrew Grimm Avatar asked Jan 06 '13 23:01

Andrew Grimm


2 Answers

Array#fill might be your ticket.

arr = []

index = 2
arr.fill( "", arr.length...index )
arr[index] = "!"
# => ["", "", "!"]

index = 5
arr.fill( "", arr.length...index )
arr[index] = "!"
# => ["", "", "!", "", "", "!"]

index = 1
arr.fill( "", arr.length...index )
arr[index] = "!"
#=> ["", "!", "!", "", "", "!"]
like image 122
dbenhur Avatar answered Sep 28 '22 01:09

dbenhur


What about using hash as array? It might look like this:

h = Hash.new do |hash,key|
  0.upto(key) { |i| hash[i] = "" unless hash.has_key?(i) }
end

h[5]
h[0] #=> ""
h[4] #=> ""
h.keys #=> [0, 1, 2, 3, 4, 5]

Maybe this approach require some additional tweaks to satisfy your demands, for example you can define method size and so on.

P.S. Get an array

h.values #=> ["", "", "", "", "", ""]
like image 32
megas Avatar answered Sep 28 '22 01:09

megas