Reputation: 6660
I have to reorder my hash of Destinations, so i want to make an array in an array like this :
@orderedDestinations = Array.new
@destinations.each do |destination|
if (destination.position != nil)
@orderedDestinations[destination.position][destination.id] = destination
end
end
I got this error :
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]=
What i am doing wrong?
Upvotes: 1
Views: 110
Reputation: 80128
If you want to sort @destinations
by Destination#position
you should just do this:
@orderedDestinations = @destinations.sort_by(&:position)
http://ruby-doc.org/core-1.9.2/Enumerable.html#method-i-sort_by
Done deal.
Upvotes: 3
Reputation: 211740
In Ruby, most things are nil
unless explicitly initialized as something. All elements of a new array, for instance, are this by default if they don't exist or haven't been assigned to previously. Like this:
test = [ 1, 2 ]
# => [1,2]
test[1]
# => 2
test[2]
# => nil
What you probably want to do is initialize the second level of the array as required. You can employ a pattern like this:
@orderedDestinations = [ ] # Empty array
@destinations.each do |destination|
if (destination.position)
# If this element of the array has not been initialized,
# populate it with a new empty array.
destination_set = @orderedDestinations[destination.position] ||= [ ]
# Put something in this second-level array spot
destination_set[destination.id] = destination
end
end
The choice of Array [ ]
or Hash { }
for your second level entry depends on the kind of data you're storing in it. Hash tables handle arbitrary identifiers easily, where an Array works best with sequential numbers typically starting at or near zero. If you initialize element X of an array, that array becomes size X+1 automatically.
Upvotes: 1
Reputation: 6660
Yes, Thank you. The solution is to add this line :
@orderedDestinations[destination.position] ||= {}
So the complete code is :
@orderedDestinations = Array.new
@destinations.each do |destination|
if (destination.position != nil)
@orderedDestinations[destination.position] ||= {}
@orderedDestinations[destination.position][destination.id] = destination
end
end
Thank you.
Upvotes: 0
Reputation: 9845
@orderedDestinations[destination.position] is nil so:
@orderedDestinations[destination.position][destination.id] really is:
-> nil[destination.id]
Upvotes: 2