J'ai un hachage qui ressemble à ceci:
hash = { 'key1' => 'value' , 'key2' => { 'sub1' => 'string' , 'sub2' => 'string' , }, 'shippingInfo' => { 'shippingType' => 'Calculated' , 'shipToLocations' => 'Worldwide' , 'expeditedShipping' => 'false' , 'oneDayShippingAvailable' => 'false' , 'handlingTime' => '3' , } }
Je dois convertir chaque valeur qui est une seule chaîne à l'intérieur d'un tableau pour qu'elle se termine comme ceci:
XXX
J'ai trouvé ceci mais je n'ai pas réussi à le faire fonctionner https://gist.github.com/chris/b4138603a8fe17e073c6bc073eb17785
p> >
3 Réponses :
Que diriez-vous de quelque chose comme:
class Hash def deep_transform_values self.transform_values do |val| next(val.first) if val.is_a?(Array) && val.length == 1 next(val) unless val.respond_to?(:deep_transform_values) val.deep_transform_values end end end
Testé avec quelque chose comme:
{ "key1"=>"value", "key2"=>{ "sub1"=>"string", "sub2"=>"string" }, "shippingInfo"=> { "shippingType"=>"Calculated", "shipToLocations"=>"Worldwide", "expeditedShipping"=>"false", "oneDayShippingAvailable"=>"false", "handlingTime"=>"3", "an_integer"=>1, "an_empty_array"=>[], "an_array_with_more_than_one_elements"=>[1, 2], "a_symbol"=>:symbol, "a_string"=>"string" } }
Donne:
hash = { 'key1' => ['value'], 'key2' => { 'sub1' => ['string'], 'sub2' => ['string'], }, 'shippingInfo' => { 'shippingType' => ['Calculated'], 'shipToLocations' => ['Worldwide'], 'expeditedShipping' => ['false'], 'oneDayShippingAvailable' => ['false'], 'handlingTime' => ['3'], 'an_integer' => 1, 'an_empty_array' => [], 'an_array_with_more_than_one_elements' => [1,2], 'a_symbol' => :symbol, 'a_string' => 'string' } }
Cela fonctionne bien pour mon cas d'utilisation. Cependant, si je voulais monkey-patch Hash classe, comment puis-je modifier cela pour qu'il fonctionne avec la récursivité afin que je puisse l'appeler sur une instance de Hash?
J'ai mis à jour la réponse avec une variante pour votre cas @lacostenycoder.
cela fonctionne très bien. Je n'ai jamais utilisé next
avec argss auparavant. Pouvez-vous m'indiquer la documentation à ce sujet?
C'est ce que le document Ruby a donc loin.
Comme alternative, envisagez d'utiliser un objet et de permettre à l'initialiseur de déconstruire certaines des clés pour vous.
L'une des raisons pour lesquelles beaucoup de gens comme moi ont commencé à utiliser Ruby en faveur de Perl était à cause de la meilleure expression d'objets à la place de primitifs comme les tableaux et les hachages. Utilisez-le à votre avantage!
class ShippingStuff # You've kept the data vague def initialize key1:, key2:, shippingInfo: @blk = -> val { val.respond_to?(:push) && val.size == 1 ? val.first : cleankeys(val) } @key1 = cleankeys key1 @key2 = cleankeys key2 @shippingInfo = shippingInfo end attr_reader :key1, :key2, :shippingInfo # basically a cut down version of what # Sebastian Palma answered with def cleankeys data if data.respond_to? :transform_values data.transform_values &@blk else @blk.call(data) end end end hash = { 'key1' => ['value'], 'key2' => { 'sub1' => ['string'], 'sub2' => ['string'], }, 'shippingInfo' => { 'shippingType' => ['Calculated'], 'shipToLocations' => ['Worldwide'], 'expeditedShipping' => ['false'], 'oneDayShippingAvailable' => ['false'], 'handlingTime' => ['3'], } } shipper = ShippingStuff.new hash.transform_keys!(&:to_sym) shipper.key1 # "value" shipper.key2 # {"sub1"=>"string", "sub2"=>"string"} shipper.shippingInfo # {"shippingType"=>["Calculated"], "shipToLocations"=>["Worldwide"], "expeditedShipping"=>["false"], "oneDayShippingAvailable"=>["false"], "handlingTime"=>["3"]}
Dans la même veine, je créerais même une classe Info
pour le code shippingInfo > data.
Vous pouvez rencontrer un problème différent si key1
et key2
sont dynamiques, mais il existe également des moyens de contourner ce problème ( double splat pour un).
C'est probablement un meilleur modèle bien qu'un peu plus rigide. La structure des données ici était un exemple non spécifique,
@lacostenycoder Bien sûr, je voulais juste donner une alternative, je ne critique pas. Le "Juste mes 2 cents" le fait peut-être passer pour une critique, probablement parce que les gens l'utilisent avant de critiquer les gens, non? Je devrais trouver une phrase de remplacement… (o_º)
recurse hash #=> {"key1"=>"value", # "key2"=>{ # "sub1"=>"string", # "sub2"=>"string" # }, # "shippingInfo"=>{ # "shippingType"=>"Calculated", # "shipToLocations"=>["Worldwide", "Web"], # "expeditedShipping"=>"false", # "oneDayShippingAvailable"=>"false", # "handlingTime"=>"3" # } # }
Je vois que ma réponse est similaire à la réponse précédente de @ Sebastian.
oui très similaire sauf en utilisant un style de commutateur mais fonctionne toujours. cela se traduit-il bien comme un patch de singe en classe Hash?