215 votes

Rails : Existe-t-il une astuce Rails pour ajouter des virgules aux grands nombres ?

Existe-t-il un moyen de faire imprimer par rails un nombre contenant des virgules ?

Par exemple, si j'ai un nombre 54000000.34, je peux exécuter <%= nombre.fonction %>, qui imprimera "54,000,000.34".

Merci !

369voto

John Topley Points 58789

Vous voulez le number_with_delimiter méthode. Par exemple :

<%= number_with_delimiter(@number, :delimiter => ',') %>

Vous pouvez également utiliser l'option number_with_precision pour s'assurer que le nombre est toujours affiché avec deux décimales de précision :

<%= number_with_precision(@number, :precision => 2, :delimiter => ',') %>

0 votes

Peut-on utiliser cette méthode dans un helper, c'est-à-dire un module ? ou est-ce seulement pour les vues ? existe-t-il une méthode équivalente pour un moudle ? merci.

5 votes

@Mo C'est une méthode d'aide à la visualisation. Vous devriez être en mesure de l'utiliser à partir d'un module en incluant ActionView::Helpers::NumberHelper au sein du module.

9 votes

Je crois que le délimiteur par défaut est une virgule, donc vous n'avez pas besoin de passer cette option dans ce cas.

140voto

pguardiario Points 19925

Pour tous ceux qui n'utilisent pas de rails :

number.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse

2 votes

Joli. Et votre réponse semble être minutieusement (une fraction de seconde seulement sur un million d'itérations) plus rapide que l'approche présentée aquí : number.to_s.reverse.scan(/(?:\d*\.)?\d{1,3}-?/).join(',').re‌​verse

0 votes

Pouvez-vous expliquer ce qui se passe ici ? nombre.to_s.reverse.gsub(/( \d {3})(?= \d )/, ' \\1 ,').reverse

7 votes

Bien sûr, il inverse la chaîne, puis ajoute une virgule après toute séquence de 3 chiffres qui est également suivie d'un autre chiffre, puis l'inverse à nouveau.

32voto

PatrikAkerstrand Points 23968

Oui, utilisez le NumberHelper . La méthode que vous recherchez est nombre_avec_délimiteur .

 number_with_delimiter(98765432.98, :delimiter => ",", :separator => ".")
 # => 98,765,432.98

19voto

coloradoblue Points 323

Si vous le faites souvent, mais aussi pour votre information, parce que ce n'est pas implicite dans ce qui précède, Rails a des valeurs par défaut raisonnables pour le paramètre number_with_delimiter méthode.

#inside controller or view
number_with_delimiter(2444323.4)
#=> 2,444,323.30

#inside console
helper.number_with_delimiter(233423)
#=> 233,423

Il n'est pas nécessaire de fournir la valeur du délimiteur si vous procédez de la manière la plus classique.

0 votes

Cela présente l'avantage supplémentaire d'utiliser la locale actuelle. C'est très important dans les applications internationales, car certaines régions utilisent la virgule comme séparateur de décimales et le point comme séparateur de milliers.

17voto

fxfilmxf Points 183

Un meilleur moyen pour ceux qui n'utilisent pas de rails qui gèrent les décimales :

parts = number.to_s.split('.')
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
parts.join('.')

Si vous voulez un délimiteur différent, changez le dernier ',' dans la regex.

En bonus, voici comment fonctionne la regex :

  • gsub remplace tout ce qui correspond à la regex par le second paramètre passé à gsub. Dans ce cas, c'est \\1 . \\1 devient \1 lorsqu'il est évalué, ce qui correspond au premier groupe de capture de l'expression rationnelle. Dans cette regex, c'est (\d) .
  • (\d)(?=(\d\d\d)+) correspond à un chiffre suivi d'un ou plusieurs groupes de 3 chiffres. Le premier groupe de parenthèses est notre \1 groupe de capture, le second serait \2 . Si nous devions en rester là, nous aurions.. : 123456.gsub!(/(\d)(?=(\d\d\d)+)/, "\\1,") #=> 1,2,3,456 C'est parce que 1234 correspond, 2345 correspond et 3456 correspond donc nous mettons une virgule après le 1, le 2 et le 3.
  • En ajoutant le ( ?!) \d ) nous faisons correspondre tout ce qui précède qui ne précède pas un chiffre donc (\d)(?=(\d\d\d)+(?!\d)) signifie correspondre à un chiffre suivi de 3 chiffres qui n'est pas suivi d'un chiffre. La raison pour laquelle cela fonctionne est que gsub va continuer à remplacer les éléments qui correspondent à la chaîne. Si nous ne devions remplacer que la première correspondance, alors pour un nombre comme 123456789, nous obtiendrions 123456,789. Puisque 123456,789 correspond toujours à notre regex, nous obtenons 123,456,789.

Voici où j'ai trouvé le code : https://github.com/rails/rails/blob/master/activesupport/lib/active_support/number_helper.rb#L298-L300

Et c'est ici que j'ai appris ce qui se passe dans cette regex : http://www.tutorialspoint.com/ruby/ruby_regular_expressions.htm

0 votes

Fonctionne comme un charme, notamment dans Liquid template lang : {{ value | round | replace: "(\d)(?=(\d\d\d)+(?!\d))", "$1," | prepend: "$" }}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X