2017-09-11 3 views
1

de mes excuses pour le titre de sondage en désordre, ne savait pas comment exprimer cela d'une manière concise ...Énumération clés de dictionnaire de rubis en utilisant les entrées du dictionnaire

Je cherche à créer un objectif général Vagrantfile à des fins diverses de test en utilisant un dictionnaire comme celui ci-dessous.

BOXES = { 
    'bo': ['zesty-lxc', 4], 
    'sw': ['zesty-lxc', 4], 
    'db': ['centos-lxc', 4] 
} 

Ce qui me donnerait une liste comme ci-dessous:

[ 
    ["bo1", "zesty-lxc"], 
    ["bo2", "zesty-lxc"], 
    ["bo3", "zesty-lxc"], 
    ["bo4", "zesty-lxc"], 
    ["sw1", "zesty-lxc"], 
    ["sw2", "zesty-lxc"], 
    ["sw3", "zesty-lxc"], 
    ["sw4", "zesty-lxc"], 
    ["db1", "centos-lxc"], 
    ["db2", "centos-lxc"], 
    ["db3", "centos-lxc"], 
    ["db4", "centos-lxc"] 
] 

que je peux alors itérer plus tard pour créer des machines.

Vagrant.configure('2') do |config| 
    box_list.each do |box, name| 
    config.vm.define name do |subconfig| 
     subconfig.vm.box = box 
     subconfig.vm.hostname = name 
    end 
    end 
end 

J'ai un peu de mal à gérer cela. J'ai réussi à imprimer exactement ce que je veux en utilisant cette construction très salissant:

BOXES.map{|key, v| ([key]*BOXES[key][1]).each.with_index(1) {|machine, count| puts "#{machine}#{count} #{BOXES[key][0]}" }} 

mais il ne imprime, je ne peux pas comprendre comment l'obtenir pour retourner la liste que je l'intention d'utiliser plus tard .

Toute aide serait appréciée, je suis très nouveau à ruby, seulement commencé à l'utiliser quand j'ai commencé à déconner avec vagabond.

Répondre

2

Vous pouvez le faire comme suit:

# We will assume this is what you meant for BOXES 
BOXES = { 
    bo: ['zesty-lxc', 4], 
    sw: ['zesty-lxc', 4], 
    db: ['centos-lxc', 4] 
} 
BOXES.map do |key,value| 
    os, number = value # assign value[0] to os and value[1] to number 
    number.times.map {|n| [key.to_s + (n + 1).to_s, os] } 
end.flatten(1) # flatten the Array 1 level 
#=> [ 
#  ["bo1", "zesty-lxc"], 
#  ["bo2", "zesty-lxc"], 
#  ["bo3", "zesty-lxc"], 
#  ["bo4", "zesty-lxc"], 
#  ["sw1", "zesty-lxc"], 
#  ["sw2", "zesty-lxc"], 
#  ["sw3", "zesty-lxc"], 
#  ["sw4", "zesty-lxc"], 
#  ["db1", "centos-lxc"], 
#  ["db2", "centos-lxc"], 
#  ["db3", "centos-lxc"], 
#  ["db4", "centos-lxc"] 
# ] 

étapes:

  • BOXES#map va créer une nouvelle Array et le rendement de chaque clé et la valeur au bloc
  • os, number = value assignera valeur [0] à os et valeur [1] à number
  • number.times.map créera un nouveau Array et en boucle à travers number nombre de fois en passant dans chaque entier (n), en commençant par 0 comme il boucle
  • [key.to_s + (n + 1).to_s, os] va créer un Array littéral avec [0] = clé et le numéro + 1 combiné en tant que chaîne et [1] = valeur
  • flatten(1) supprimera l'imbrication Array créée par number.times.map
+0

C'est incroyable, fonctionne parfaitement. Je devrais vraiment apprendre le rubis juste pour obtenir ma tête autour de cette incroyable SUCRE! Python va toujours être ma principale référence, mais ça a l'air tellement amusant! – sharktamer

1
result = BOXES.each_with_object([]) do |(k, v), memo| 
    (1 .. v.last).each do |i| 
    memo << [k.to_s + i.to_s, v.first] 
    end 
end