web-dev-qa-db-fra.com

Conversion de chaîne de snake_case en CamelCase en Ruby

J'essaye de convertir un nom de cas de serpent en cas de chameau. Existe-t-il des méthodes intégrées?

Par exemple: "app_user" à "AppUser"

(J'ai une chaîne "app_user" Je veux convertir cela en modèle AppUser).

157
Lohith MV

Si vous utilisez Rails, String # camelize est ce que vous recherchez.

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

Si vous voulez obtenir une classe réelle, vous devez utiliser String # constantize en plus de cela.

"app_user".camelize.constantize
228
Sergio Tulentsev

Celui-ci, ça va?

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

Trouvé dans les commentaires ici: Classe a Ruby chaîne

Voir le commentaire de Wayne Conrad

109
user3869936

Utilisez classify. Il gère bien les cas Edge.

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

Remarque:

Cette réponse est spécifique à la description donnée dans la question (elle n'est pas spécifique au titre de la question). Si on essaie de convertir une chaîne en chameaux, ils doivent utiliser la réponse de Sergio . Le questionneur déclare qu'il veut convertir app_user à AppUser (pas App_user), d’où cette réponse ..

40
Harish Shetty

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

À des fins d'apprentissage:

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"

Et pour la variante lowerCase:

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"
23
Mr. Black

Indice de référence pour les solutions pures Ruby

J'ai pris toutes les possibilités que j'avais à l'esprit pour le faire avec du code pur Ruby), les voici:

  • capitaliser et gsub

    "app_user".capitalize.gsub(/_(\w)/){$1.upcase}
    
  • diviser et mapper en utilisant & abrégé (grâce à la réponse de user3869936)

    "app_user".split('_').map(&:capitalize).join
    
  • découper et cartographier (grâce à la réponse de M. Black)

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

Et voici la référence pour tout cela, nous pouvons voir que gsub est assez mauvais pour cela. J'ai utilisé 126 080 mots.

                              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)
15
Ulysse BN

Je suis venu ici pour chercher l'inverse de votre question, allant d'un cas de chameau à un cas de serpent. Utilisez trait de soulignement pour cela (non décamélisé):

AppUser.name.underscore # => "app_user"

ou, si vous avez déjà une chaîne de cas de chameau:

"AppUser".underscore # => "app_user"

ou, si vous voulez obtenir le nom de la table, c'est probablement pour cette raison que vous voulez le cas snake:

AppUser.name.tableize # => "app_users"

9
mike

Je me sens un peu mal à l'aise d'ajouter d'autres réponses ici. Nous avons décidé d’utiliser l’approche pure Ruby) la plus lisible et minimale, en ignorant le point de repère de Nice provenant de @ ulysse-bn. Bien que le mode :class soit une copie de @ user3869936, le :method mode Je ne vois aucune autre réponse ici.

  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

Le résultat est:

[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
akostadinov

La plupart des autres méthodes listées ici sont spécifiques à Rails). Si vous voulez le faire avec du pur Ruby, voici la manière la plus concise que j'ai trouvée (grâce à @ ulysse-bn pour l'amélioration suggérée)

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

Étendre la chaîne pour ajouter Camelize

En pure Ruby vous pouvez étendre la classe de chaîne en utilisant exactement le même code que Rails .camelize

class String
  def camelize(uppercase_first_letter = true)
    string = self
    if uppercase_first_letter
      string = string.sub(/^[a-z\d]*/) { |match| match.capitalize }
    else
      string = string.sub(/^(?:(?=\b|[A-Z_])|\w)/) { |match| match.downcase }
    end
    string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub("/", "::")
  end
end
0