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?