2012-03-01 31 views

Respuesta

189

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

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

Si desea obtener una clase real, se debe utilizar String#constantize por encima de eso.

"app_user".camelize.constantize 
+30

se debe añadir que se trata de una adición a los carriles de cuerda, que no funciona con Ruby puro. – iGEL

+1

Está etiquetado como 'ruby-on-rails', así que supongo que no es un problema. Pero gracias por mencionarlo –

+6

No es necesario camelize antes de la constante. Use '# classify' en su lugar. '" some_namespace/module/class_name ".classify =>" SomeNamespace :: Module :: ClassName "' –

40

Use classify. Maneja bien las cajas de borde.

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

Nota:

Esta respuesta es específica a la descripción dada en la pregunta (que no es específico para el título de la pregunta). Si uno trata de convertir una cuerda en camel-case, debe usar la respuesta Sergio. El interlocutor dice que quiere convertir a app_userAppUser (no App_user), por lo tanto, esta respuesta ..

+4

Para entornos Rails, esto es perfecto. – ghayes

+0

Tenga en cuenta que 'classify' devuelve una cadena, luego debe llamar a' constantize' para convertirla en una clase real. – Stefan

+1

Una advertencia importante con 'classify' es que las cadenas pluralizadas se volverán singulares ...' 'age_in_years'.classify' se convierte en 'AgeInYear' – br3nt

21

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 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" 
+2

¿No deberíamos estar aprendiendo a no reinventar la rueda? – pguardiario

+5

@pguardiario eso es después de que aprendimos cómo funciona la rueda. – caesarsol

+5

@pguardiario si la rueda se llama * ActiveSupport *, reinventalo. – shime

9

Encontré aquí buscando el inverso de su pregunta, yendo de camel case a s caso nake. Utilice underscore para que (no decamelize):

AppUser.name.underscore # => "app_user"

o, si ya tiene una cadena caso de camellos:

"AppUser".underscore # => "app_user"

o, si se desea obtener el nombre de la tabla, que es, probablemente, por qué te gustaría el caso de la serpiente:

AppUser.name.tableize # => "app_users"

1

La mayoría de los otros métodos enumerados aquí son específicos de Rails. Si no desea hacer esto con Ruby puro, la siguiente es la forma más concisa que he llegado con (gracias a @ ulysse-bn para la mejora sugerida)

x="this_should_be_camel_case" 
x.gsub(/(?:_|^)(\w)/){$1.upcase} 
    #=> "ThisShouldBeCamelCase" 
+0

Su definición de "camel case" es demasiado limitada. Los nombres de clase en Java y Ruby, por ejemplo, * son * camel case MyFavoriteClass ... pero tampoco tienen una letra inicial de mayúscula inferior.a veces el estuche de camello tiene límites iniciales. a veces no. – masukomi

+0

Usar 2 Regex donde puede usar solo uno es exagerado. Solo puede usar el grupo que no captura: 'x.gsub (/ (?: _ | ^) (\ W) /) {$ 1.upcase}' –

85

¿Qué tal este?

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

encontrados en los comentarios aquí: Classify a Ruby string

Véase el comentario del Wayne Conrad

+8

Usted es increíble, gracias. No quería tener que incluir bibliotecas de rieles solo para una tarea tan pequeña. Esto es hermoso. :) – Gerry

+8

Esta es la única respuesta real a la pregunta. No usa las bibliotecas de Rails. –

8

de referencia para soluciones de rubíes puros

que tomé cada posibilidades que tenía en mente para hacerlo con el código de rubí puro , aquí están:

  • capitalizar y gsub

    "app_user".capitalize.gsub(/_(\w)/){$1.upcase} 
    
  • dividida y mapa utilizando & abreviada (gracias a la respuesta de user3869936)

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

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

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

       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) 
0

Me siento un poco incómodo para agregar más respuestas aquí. Decidió optar por el enfoque ruby ​​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 aparece 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" 
Cuestiones relacionadas