Convertir cadena de snake case a camelCase en Ruby


Estoy tratando de convertir un nombre de snake case a camel case. ¿Hay algún método incorporado?

Por ejemplo: "app_user" a "AppUser"

(Tengo una cadena "app_user" que quiero convertir en modelo AppUser).

Author: Stefan, 2012-03-02

8 answers

Si estás usando Rails, String#camelize es lo que estás buscando.

  "active_record".camelize                # => "ActiveRecord"
  "active_record".camelize(:lower)        # => "activeRecord"

Si desea obtener una clase real, debe usar String#constantize encima de eso.

"app_user".camelize.constantize
 199
Author: Sergio Tulentsev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-07 09:28:44

¿Qué tal este?

"hello_world".split('_').collect(&:capitalize).join #=> "HelloWorld"

Encontrado en los comentarios aquí: Clasificar una cadena de Ruby

Ver comentario de Wayne Conrad

 92
Author: user3869936,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:33:26

Use classify. Maneja bien los casos de borde.

"app_user".classify # => AppUser
"user_links".classify   # => UserLink

Nota:

Esta respuesta es específica a la descripción dada en la pregunta(no es específica al título de la pregunta). Si uno está tratando de convertir una cadena a camel-case debe usar La respuesta de Sergio. El interrogador afirma que quiere convertir app_user a AppUser (no App_user), de ahí esta respuesta..

 40
Author: Harish Shetty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:33:26

Fuente: http://rubydoc.info/gems/extlib/0.9.15/String#camel_case-instance_method

Con fines de aprendizaje:

class String
  def camel_case
    return self if self !~ /_/ && self =~ /[A-Z]+.*/
    split('_').map{|e| e.capitalize}.join
  end
end

"foo_bar".camel_case          #=> "FooBar"

Y para la variante en minúsculas:

class String
  def camel_case_lower
    self.split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
  end
end

"foo_bar".camel_case_lower          #=> "fooBar"
 22
Author: Mr. Black,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-07 09:30:07

Punto de referencia para soluciones pure Ruby

Tomé todas las posibilidades que tenía en mente para hacerlo con código ruby puro, aquí están :

  • Capitalizar y gsub

    "app_user".capitalize.gsub(/_(\w)/){$1.upcase}
    
  • Dividir y mapear usando & taquigrafía (gracias a la respuesta de user3869936)

    "app_user".split('_').map(&:capitalize).join
    
  • Dividir y mapa (gracias a la respuesta del Sr. Black)

    "app_user".split('_').map{|e| e.capitalize}.join
    

Y aquí está el punto de referencia para todos estos, podemos ver que gsub es bastante malo para esto. Usé 126 080 palabra.

                              user     system      total        real
capitalize and gsub  :      0.360000   0.000000   0.360000 (  0.357472)
split and map, with &:      0.190000   0.000000   0.190000 (  0.189493)
split and map        :      0.170000   0.000000   0.170000 (  0.171859)
 12
Author: Ulysse BN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-25 18:58:05

Llegué aquí buscando el inverso de tu pregunta, pasando del caso del camello al caso de la serpiente. Use subrayado para eso (no descamelizar):

AppUser.name.underscore # => "app_user"

O, si ya tiene una cadena camel case:

"AppUser".underscore # => "app_user"

O, si desea obtener el nombre de la tabla, que es probablemente la razón por la que querría el caso de la serpiente:

AppUser.name.tableize # => "app_users"

 9
Author: mike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-06 23:06:02

Me siento un poco incómodo para agregar más respuestas aquí. Decidió optar por el enfoque de rubí puro más legible y mínimo, sin tener en cuenta el buen punto de referencia de @ulysse-bn. Mientras que el modo :class es una copia de @user3869936, el modo :method no lo veo en ninguna otra respuesta aquí.

  def snake_to_camel_case(str, mode: :class)
    case mode
    when :class
      str.split('_').map(&:capitalize).join
    when :method
      str.split('_').inject { |m, p| m + p.capitalize }
    else
      raise "unknown mode #{mode.inspect}"
    end
  end

El resultado es:

[28] pry(main)> snake_to_camel_case("asd_dsa_fds", mode: :class)
=> "AsdDsaFds"
[29] pry(main)> snake_to_camel_case("asd_dsa_fds", mode: :method)
=> "asdDsaFds"
 2
Author: akostadinov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-16 13:17:19

La mayoría de los otros métodos listados aquí son específicos de Rails. Si quieres hacer esto con pure Ruby, la siguiente es la forma más concisa que se me ha ocurrido (gracias a @ulysse-bn por la mejora sugerida)

x="this_should_be_camel_case"
x.gsub(/(?:_|^)(\w)/){$1.upcase}
    #=> "ThisShouldBeCamelCase"
 0
Author: masukomi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-06 16:42:02