Я пытаюсь преобразовать имя из случая змеи в случай верблюда. Есть ли встроенные методы?
Например: "app_user"
к"AppUser"
(У меня есть строка, которую "app_user"
я хочу преобразовать в модель AppUser
).
Я пытаюсь преобразовать имя из случая змеи в случай верблюда. Есть ли встроенные методы?
Например: "app_user"
к"AppUser"
(У меня есть строка, которую "app_user"
я хочу преобразовать в модель AppUser
).
Ответы:
Если вы используете Rails, String # camelize - это то, что вы ищете.
"active_record".camelize # => "ActiveRecord"
"active_record".camelize(:lower) # => "activeRecord"
Если вы хотите получить реальный класс, вы должны использовать String # constantize поверх этого.
"app_user".camelize.constantize
ruby-on-rails
, так что, я думаю, это не проблема. Но спасибо за упоминание.
#classify
вместо этого. "some_namespace/module/class_name".classify => "SomeNamespace::Module::ClassName"
require "active_support/core_ext/string"
достаточно, если уже установлен Rails.
Как насчет этого?
"hello_world".split('_').collect(&:capitalize).join #=> "HelloWorld"
Найдено в комментариях здесь: классифицировать рубиновые строки
См. Комментарий Уэйна Конрада
Если вы используете Rails, используйте classify
. Хорошо обрабатывает крайние случаи.
"app_user".classify # => AppUser
"user_links".classify # => UserLink
Примечание:
Этот ответ является специфическим для описания, приведенного в вопросе (он не является специфичным для названия вопроса). Если кто-то пытается преобразовать строку в случай верблюда, он должен использовать ответ Серхио . Спрашивающий заявляет, что он хочет преобразовать app_user
в AppUser
(не App_user
), следовательно, этот ответ ..
classify
возвращает строку, которую вы должны constantize
впоследствии вызвать, чтобы преобразовать ее в фактический класс.
classify
является то, что множественные строки станут единичными ... 'age_in_years'.classify
становитсяAgeInYear
4.2.11
Источник: http://rubydoc.info/gems/extlib/0.9.15/String#camel_case-instance_method
Для учебной цели:
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"
И для варианта в нижнем регистре:
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"
self.split('_').inject([]){ |buffer,e| buffer + [buffer.empty? ? e : e.capitalize] }.join
Я использовал все возможности, которые имел в виду, чтобы сделать это с чистым кодом ruby, вот они:
использовать заглавные буквы и gsub
'app_user'.capitalize.gsub(/_(\w)/){$1.upcase}
разделить и отобразить с помощью &
стенографии (благодаря ответу пользователя 3869936)
'app_user'.split('_').map(&:capitalize).join
раскол и карта (благодаря ответу мистера Блэка)
'app_user'.split('_').map{|e| e.capitalize}.join
И вот эталон для всего этого, мы видим, что gsub довольно плох для этого. Я использовал 126 080 слов.
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)
Я попал сюда в поисках обратной стороны вашего вопроса: от верблюжьей до змеиной. Для этого используйте подчеркивание (не декамелизуйте):
AppUser.name.underscore # => "app_user"
или, если у вас уже есть строка с верблюжьим регистром:
"AppUser".underscore # => "app_user"
или, если вы хотите получить имя таблицы, возможно, поэтому вам нужен случай со змеей:
AppUser.name.tableize # => "app_users"
AppUser.table_name
? Вы также убедитесь, что у вас есть истинное имя таблицы, если это не app_users, а что-то определенное в другом месте.
Я чувствую себя немного неловко, чтобы добавить больше ответов здесь. Решил пойти на наиболее читабельный и минимальный метод чистого рубина, не обращая внимания на хороший тест @ ulysse-bn. Хотя :class
mode является копией @ user3869936, этот :method
режим я не вижу здесь ни в одном другом ответе.
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
Результат:
[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"
PascalCase
что это подмножество CamelCase
. И это то, что я знал - этот случай с верблюдом относился к обоим. Но я никогда не исследовал. Спасибо за упоминание PascalCase, хотя. en.wikipedia.org/wiki/Camel_case
:method
версия делала downcase
первый, чтобы ее можно было использовать как для, так lower_snake_case
и для UPPER_SNAKE_CASE
.
Большинство других методов, перечисленных здесь, специфичны для Rails. Если вы хотите сделать это с чистым Ruby, ниже приведен самый краткий способ, которым я придумал (спасибо @ ulysse-bn за предложенное улучшение)
x="this_should_be_camel_case"
x.gsub(/(?:_|^)(\w)/){$1.upcase}
#=> "ThisShouldBeCamelCase"
x.gsub(/(?:_|^)(\w)/){$1.upcase}
gsub
решению, которое кажется медленнее по сравнению с map
решением.
В чистом Ruby вы можете расширить строковый класс, используя точно такой же код из 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