Converting string from snake_case to CamelCase in Ruby

前端 未结 10 1053
情书的邮戳
情书的邮戳 2020-11-30 19:57

I am trying to convert a name from snake case to camel case. Are there any built-in methods?

Eg: \"app_user\" to \"AppUser\"

(I hav

相关标签:
10条回答
  • If you're using Rails, String#camelize is what you're looking for.

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

    If you want to get an actual class, you should use String#constantize on top of that.

    "app_user".camelize.constantize
    
    0 讨论(0)
  • 2020-11-30 20:33

    The ruby core itself has no support to convert a string from snake case to (upper) camel case (also known as pascal case).

    So you need either to make your own implementation or use an existing gem.

    There is a small ruby gem called lucky_case which allows you to convert a string from any of the 10+ supported cases to another case easily:

    require 'lucky_case'
    
    # to get upper camel case (pascal case) as string
    LuckyCase.pascal_case('app_user') # => 'AppUser'
    # to get the pascal case constant
    LuckyCase.constantize('app_user') # => AppUser
    # or the opposite way
    LuckyCase.snake_case('AppUser')   # => app_user
    

    You can even monkey patch the String class if you want to:

    require 'lucky_case/string'
    
    'app_user'.pascal_case # => 'AppUser'
    'app_user'.constantize # => AppUser
    # ...
    

    Have a look at the offical repository for more examples and documentation:

    https://github.com/magynhard/lucky_case

    0 讨论(0)
  • 2020-11-30 20:34

    Benchmark for pure Ruby solutions

    I took every possibilities I had in mind to do it with pure ruby code, here they are :

    • capitalize and gsub

      'app_user'.capitalize.gsub(/_(\w)/){$1.upcase}
      
    • split and map using & shorthand (thanks to user3869936’s answer)

      'app_user'.split('_').map(&:capitalize).join
      
    • split and map (thanks to Mr. Black’s answer)

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

    And here is the Benchmark for all of these, we can see that gsub is quite bad for this. I used 126 080 words.

                                  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 讨论(0)
  • 2020-11-30 20:36

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

    For learning purpose:

    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"
    

    And for the lowerCase variant:

    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"
    
    0 讨论(0)
  • 2020-11-30 20:36

    Most of the other methods listed here are Rails specific. If you want do do this with pure Ruby, the following is the most concise way I've come up with (thanks to @ulysse-bn for the suggested improvement)

    x="this_should_be_camel_case"
    x.gsub(/(?:_|^)(\w)/){$1.upcase}
        #=> "ThisShouldBeCamelCase"
    
    0 讨论(0)
  • 2020-11-30 20:36

    Extend String to Add Camelize

    In pure Ruby you could extend the string class using the exact same code from 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 讨论(0)
提交回复
热议问题