2012-03-01 19 views

risposta

189

Se si utilizza Rails, String#camelize è quello che stai cercando.

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

Se si desidera ottenere una classe reale, si dovrebbe usare String#constantize in cima a quello.

"app_user".camelize.constantize 
+30

Si dovrebbe aggiungere che questo è un Rails aggiunta alla stringa, non funziona con pura Ruby. – iGEL

+1

È etichettato 'ruby-on-rails', quindi, immagino, non è un problema. Ma grazie per averlo menzionato. –

+6

Non è necessario camelizzare prima di essere costante. Usa invece '# classify'. '" some_namespace/module/class_name ".classify =>" SomeNamespace :: Module :: ClassName "' –

40

Utilizzare classify. Gestisce bene i casi limite.

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

Nota:

Questa risposta è specifico per la descrizione fornita nella domanda (che non è specifico per il titolo della domanda). Se si sta provando a convertire una stringa in un caso di cammello, dovrebbero usare la risposta di Sergio. L'interrogante afferma che vuole convertire app_user-AppUser (non App_user), quindi questa risposta ..

+4

Per gli ambienti Rails, questo è perfetto. – ghayes

+0

Nota che 'classify' restituisce una stringa, devi chiamare' constantize' in seguito per convertirla in una classe reale. – Stefan

+1

Un avvertimento importante con 'classify' è che le stringhe pluralizzate diventeranno singolari ...' 'age_in_years'.classify' diventa 'AgeInYear' – br3nt

21

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

fini di apprendimento:

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" 

E per la variante minuscole:

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

Non dovremmo imparare a non reinventare la ruota? – pguardiario

+5

@pguardiario, dopo aver appreso come funziona la ruota. – caesarsol

+5

@pguardiario se si chiama la ruota * ActiveSupport *, reinventarlo. – shime

9

Sono arrivato qui cercando l'inverso della tua domanda, passando da caso cammello a s caso originale. Utilizzare underscore per questo (non decamelize):

AppUser.name.underscore # => "app_user"

o, se si dispone già di una stringa caso cammello:

"AppUser".underscore # => "app_user"

o, se si vuole ottenere il nome della tabella, che è probabilmente il motivo per cui ci si vuole il caso serpente:

AppUser.name.tableize # => "app_users"

1

La maggior parte degli altri metodi elencati qui sono specifici di Rails. Se si vuole fare fare questo con puro Ruby, il seguente è il modo più conciso mi è venuta in mente (grazie a @ Ulysse-bn per il miglioramento suggerito)

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

La tua definizione di "caso cammello" è troppo limitata. I nomi delle classi in Java e Ruby, ad esempio, * sono * casi cammello MyFavoriteClass ... ma non hanno una lettera iniziale con involucro inferiore.a volte il caso dei cammelli ha i cappucci iniziali. a volte no. – masukomi

+0

L'utilizzo di 2 Regex in cui è possibile utilizzare solo uno è eccessivo. Puoi utilizzare solo gruppi non di acquisizione: 'x.gsub (/ (?: _ | ^) (\ W) /) {$ 1.upcase}' –

85

Che ne dici di questo?

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

Trovato nei commenti qui: Classify a Ruby string

See commento di Wayne Conrad

+8

Sei fantastico, grazie. Non volevo includere librerie di rails solo per un'attività così piccola. Questo è bellissimo. :) – Gerry

+8

Questa è una delle uniche risposte reali alla domanda. Non usando le librerie di Rails. –

8

riferimento per le soluzioni di Ruby puro

ho preso ogni possibilità che avevo in mente di farlo con codice Ruby puro , eccoli:

  • capitalizzare e gsub

    "app_user".capitalize.gsub(/_(\w)/){$1.upcase} 
    
  • diviso e mappa utilizzando & stenografia (grazie alla risposta di user3869936)

    "app_user".split('_').map(&:capitalize).join 
    
  • punte e mappa (grazie alla risposta di Mr. Black)

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

Ed ecco il punto di riferimento per tutti questi, noi puoi vedere che gsub è abbastanza cattivo per questo. Ho usato 126 080 parole.

       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

Mi sento un po 'a disagio per aggiungere più risposte qui. Ho deciso di optare per l'approccio Ruby puramente leggibile e minimale, ignorando il bel benchmark di @ ulysse-bn. Mentre la modalità :class è una copia di @ user3869936, la modalità :method non vedo in nessuna altra risposta qui.

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 

risultato è:

[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" 
Problemi correlati