2011-06-11 5 views
2

Supposons que j'aie 2 objets, chacun ayant un emplacement particulier numéroté de 1 à 5 (unique). Dire que object1 a fente = 3 et fente object2 = 5. Quel est un moyen efficace de créer un hachage comme:Objets cartographiques basés sur la valeur d'index

{ 1 => nil, 2 => nil, 3 => object1, 4 => nil, 5 => object2} 

Je suppose que la carte pourrait être utilisée, mais quelle est la meilleure façon?

EDIT: 5 est juste un exemple, s'il vous plaît prétendre que vous ne connaissez pas le nombre de slots.

+0

par "unique" vous voulez dire que différents objets peuvent * pas * (modifier) ​​contenir la même valeur? – tokland

+0

ne peut pas contenir la même valeur :) Seul 1 objet a l'emplacement numéro 3, par exemple. – Spyros

Répondre

3
require 'ostruct' 
objects =[OpenStruct.new(:slot => 3), OpenStruct.new(:slot => 5)] 
base = Hash[(1..5).map { |x| [x, nil] }] # also: Hash[(1..5).zip] 
#=> {1=>nil, 2=>nil, 3=>nil, 4=>nil, 5=>nil} 
merged = base.merge(Hash[objects.map(&:slot).zip(objects)]) 
#=> {1=>nil, 2=>nil, 3=>#<OpenStruct slot=3>, 4=>nil, 5=>#<OpenStruct slot=5>} 

aussi:

slots = Hash[objects.map(&:slot).zip(objects)] 
#=> {3=>#<OpenStruct slot=3>, 5=>#<OpenStruct slot=5>} 
merged = Hash[(1..5).map { |slot| [slot, slots[slot]] }] 
#=> {1=>nil, 2=>nil, 3=>#<OpenStruct slot=3>, 4=>nil, 5=>#<OpenStruct slot=5>} 
+0

celui-ci semble être une bonne solution, laissez-moi le tester un peu. – Spyros

+0

Et s'il y a plus de 5 emplacements? – Wes

+0

@Wes: Remplacez (1..5) par le tableau des slots, quel qu'il soit. – tokland

1

Vous pouvez simplement utiliser un tableau, à savoir:

% irb 
>> object1 = Object.new 
=> #<Object:0x1005ad010> 
>> object2 = Object.new 
=> #<Object:0x1005861e0> 
>> list = Array.new 
=> [] 
>> list[3] = object1 
=> #<Object:0x1005ad010> 
>> list[5] = object2 
=> #<Object:0x1005861e0> 
>> list 
=> [nil, nil, nil, #<Object:0x1005ad010>, nil, #<Object:0x1005861e0>] 

De là, vous pouvez répondre à object1 dans l'index 3 et objet 2 dans l'index 5. tableaux Ruby sont pratiques pour cela car ils vont remplir avec nils lorsque vous ajoutez un élément au-delà de la fin du tableau.

0

Je voudrais utiliser un tableau car il est plus approprié pour votre référence et a nils par défaut. Le 1 revêtement suivant illustre l'utilisation (en utilisant OpenStruct comme mon objet):

> [OpenStruct.new(:slot => 3), OpenStruct.new(:slot => 5)].inject([]) {|s,o| s[o.slot-1] = o; s} 
=> [nil, nil, #<OpenStruct slot=3>, nil, #<OpenStruct slot=5>] 

Si vous ne voulez vraiment un hachage alors je déterminer l'emplacement maximum des objets eux-mêmes comme ce qui suit:

> a = [OpenStruct.new(:slot => 3), OpenStruct.new(:slot => 7)] 
=> [#<OpenStruct slot=3>, #<OpenStruct slot=7>] 
> range = 1..a.inject(0) {|s,o| (o.slot>s) ? o.slot : s} 
=> 1..7 
> h = Hash[range.map {|v| [v,nil]}] 
=> {1=>nil, 2=>nil, 3=>nil, 4=>nil, 5=>nil, 6=>nil, 7=>nil} 
> h.merge(Hash[a.map {|v| [v.slot, v]}]) 
=> {1=>nil, 2=>nil, 3=>#<OpenStruct slot=3>, 4=>nil, 5=>nil, 6=>nil, 7=>#<OpenStruct slot=7>} 
Questions connexes