Quiero capitalizar los elementos de cadena en la matriz con ruby

Este es mi código:

headermonths = ["января","февраля","марта","апреля","мая","июня","июля","августа","октября","ноября","декабря"]

headermonths.each {|month| month.capitalize!}
puts headermonths

Obtengo la siguiente salida:

января
февраля
марта
апреля
мая
июня
июля
августа
октября
ноября
декабря

Si imprime la matriz con:

 print headermonths    

Me sale lo siguiente

["\u044F\u043D\u0432\u0430\u0440\u044F", "\u0444\u0435\u0432\u0440\u0430\u043B\u044F", "\u043C\u0430\u0440\u0442\u0430", "\u0430\u043F\u0440\u0435\u043B\u044F", "\u043C\u0430\u044F", "\u0438\u044E\u043D\u044F", "\u0438\u044E\u043B\u044F", "\u0430\u0432\u0433\u0443\u0441\u0442\u0430", "\u043E\u043A\u0442\u044F\u0431\u0440\u044F", "\u043D\u043E\u044F\u0431\u0440\u044F", "\u0434\u0435\u043A\u0430\u0431\u0440\u044F"]

Pero me gustaría tener una salida como:

Января Февраля Марта Апреля Мая Июня Июля Августа Октября Ноября Декабря

¿Cómo consigo esto con un método de rubí?

4
Chlodwig Radulf 23 dic. 2016 a las 15:19

3 respuestas

La mejor respuesta

Puede usar la gema unicode

require 'unicode'

headermonths = ["января","февраля","марта","апреля","мая","июня","июля","августа","октября","ноября","декабря"]

headermonths.map! {|month| Unicode::capitalize month }
puts headermonths
# >> ["Января", "Февраля", "Марта", "Апреля", "Мая", "Июня", "Июля", "Августа", "Октября", "Ноября", "Декабря"]
2
Sergio Tulentsev 23 dic. 2016 a las 13:00

Solución independiente:

# From : https://en.wikipedia.org/wiki/Cyrillic_alphabets :
upcase   = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"
downcase = "абвгдежзийклмнопрстуфхцчшщьюя"

headermonths = ["января","февраля","марта","апреля","мая","июня","июля","августа","октября","ноября","декабря"]

headermonths.each{|word| word[0] = word[0].tr(downcase,upcase)}
# => ["Января", "Февраля", "Марта", "Апреля", "Мая", "Июня", "Июля", "Августа", "Октября", "Ноября", "Декабря"]

Si desea usarlo con palabras en alfabetos latinos y cirílicos:

headermonths.each{|word| word[0] = word[0].tr(downcase,upcase).upcase }

Con ActiveSupport

Puede usar ActiveSupport :: Multibyte:

require 'active_support/core_ext/string/multibyte'
"января".mb_chars.capitalize.to_s #=> "Января"

Entonces tu guión se convierte en:

require 'active_support/core_ext/string/multibyte'

headermonths = ["января","февраля","марта","апреля","мая","июня","июля","августа","октября","ноября","декабря"]

headermonths.map!{|word| word.mb_chars.capitalize.to_s}
#=> ["Января", "Февраля", "Марта", "Апреля", "Мая", "Июня", "Июля", "Августа", "Октября", "Ноября", "Декабря"]

Ruby 2.4

El código en su pregunta funcionaría tal como se esperaba con Ruby 2.4.

Consulte "Mayúsculas y minúsculas para caracteres unicode" aquí.

2
Eric Duminil 23 dic. 2016 a las 16:14

El siguiente ejemplo es una versión robusta en mayúscula, que funciona en cualquier rubí comenzando con 1.9 pero solo para cirílico debido a -32 codificado .

NB : gracias y créditos a @Stefan y @EricDuminil, quienes me guiaron en la dirección correcta

headermonths = %w|января февраля марта апреля мая июня
                  июля августа октября ноября декабря|
puts (headermonths.each do |s|
  s[0] = (s[0].ord - 32).chr(Encoding::UTF_8) 
end.inspect)
#⇒ ["Января", "Февраля", "Марта", "Апреля", "Мая", "Июня",
#   "Июля", "Августа", "Октября", "Ноября", "Декабря"]
1
Aleksei Matiushkin 23 dic. 2016 a las 18:37