2012-11-12 4 views
2

J'ai un hachage de types mixtes:Ruby interpolation de hachage

stuff = {:pack_one => ["blue_item", "red_item"], :pack_two => [:green_item, :purple_item, :yellow_item]} 

Et je dois convertir en une phrase comme:

"pack_one contains a blue_item and red_item and pack_two contains a green_item, purple_item and yellow_item" 

donc je suppose que je dois utiliser Enumerable et itérer le hachage et construire la phrase, mais je ne suis pas sûr de savoir comment?

+0

À quel point visiez-vous la grammaire correcte? –

Répondre

0

Voici une solution, en utilisant Enumerable#map et Array#join:

stuff.map do |k, v| 
    "#{k} contains a #{v.size > 2 ? v[0..-2].join(", ") + " and " + v[-1].to_s : v.join(' and ')}" 
end.join(" and ") 
=> "pack_one contains a blue_item and red_item and pack_two contains green_item and purple_item and yellow_item" 

Edit: Maintenant, correspond parfaitement à vos besoins.

6

Ma solution. Exigences d'ajustement un peu plus strictes que la réponse @Eureka.

strings = stuff.map do |key, values| 
    "#{key} contains a #{values[0..-2] * ', '} and #{values.last}" 
end 
puts strings.join ' and ' 
+0

Intelligent et court en effet (je n'ai pas pensé à cette façon de se débarrasser de l'opérateur ternaire) :) – Eureka

+1

Ne connaissait pas cette utilisation de tableau # *; Array # join est certainement plus idiomatique, mais j'apprécie à quel point c'est laconique! –

+0

join ne semble pas être défini pour le hachage. –

3

Si vous pouvez utiliser ActiveSupport, voici un tricheur:

require 'active_support/core_ext/array/conversions' 
stuff.map{|k,v| "#{k} contains a #{v.to_sentence}"}.join(" and ") 

Résultat:

1.9.3p125 > require 'active_support/core_ext/array/conversions' 
=> true 
1.9.3p125 > stuff.map{|k,v| "#{k} contains a #{v.to_sentence}"}.join(" and ") 
=> "pack_one contains a blue_item and red_item and pack_two contains a green_item, purple_item, and yellow_item" 

EDIT: Pour se débarrasser de la virgule Oxford, explicitement fournir l'option last_word_connector:

1.9.3p125 > stuff.map{|k,v| "#{k} contains a #{v.to_sentence(last_word_connector: " and ")}"}.join(" and ") 
=> "pack_one contains a blue_item and red_item and pack_two contains a green_item, purple_item and yellow_item" 
+0

+1 c'est ce que je pensais. –