সাপ_কেস থেকে রুবির ক্যামেলকেসে স্ট্রিং রূপান্তর করা


171

আমি সাপের কেস থেকে একটি নাম উটের ক্ষেত্রে রূপান্তরিত করার চেষ্টা করছি। কোন অন্তর্নির্মিত পদ্ধতি আছে?

যেমন: "app_user"থেকে"AppUser"

(আমার কাছে একটি স্ট্রিং রয়েছে যা "app_user"আমি এটিকে মডেলে রূপান্তর করতে চাই AppUser)।

উত্তর:


251

আপনি যদি রেলগুলি ব্যবহার করেন তবে স্ট্রিং # ক্যামিটাইজ হ'ল আপনি যা খুঁজছেন তা।

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

আপনি যদি আসল ক্লাস পেতে চান তবে তার উপরে আপনার স্ট্রিং # কনস্ট্যান্টাইজ ব্যবহার করা উচিত ।

"app_user".camelize.constantize

44
আপনার যুক্ত করা উচিত যে এটি স্ট্রিংয়ের জন্য একটি রেল সংযোজন, এটি খাঁটি রুবির সাথে কাজ করে না।
আইগেল

2
এটি ট্যাগ করা হয়েছে ruby-on-rails, সুতরাং, আমার ধারণা, এটি কোনও সমস্যা নয়। তবে উল্লেখ করার জন্য ধন্যবাদ।
সেরজিও টুলেন্টসেভ

6
কনস্ট্যান্টাইজিংয়ের আগে আপনাকে উটপাখির দরকার নেই। #classifyপরিবর্তে ব্যবহার করুন। "some_namespace/module/class_name".classify => "SomeNamespace::Module::ClassName"
ক্রিস হিল্ড

5
@ ক্রিস # ক্লাসিফাই: এক নয়। # শ্রেণিবদ্ধ একটি স্ট্রিং প্রত্যাবর্তন করে, যেখানে # কনস্ট্রিটিজ প্রসঙ্গে ধ্রুবক হিসাবে দেখায় (এবং উটচিহ্নের প্রয়োজন হয়)। 'অ্যাক্টিভ_রেকার্ড' কনটেনটিজ ত্রুটি দেয়, 'অ্যাক্টিভ_রেকার্ড'। কমেলাইজ.কনস্টিটিজ স্থির অ্যাক্টিভেকর্ডকে ফিরিয়ে দেয়, 'অ্যাক্টিভ_রেকর্ড'। ক্লাসিফাই 'অ্যাক্টিভেকর্ড' স্ট্রিংটি প্রদান করে। এবং যদি আপনি 'no_class'.camelize.constantize করেন তবে আপনি ত্রুটি পেয়ে যাবেন (এমন ধ্রুবক NoClass নেই) তবে' no_class'.classif খুশিতে 'NoClass' স্ট্রিংটি ফেরত দেয়।
কানাত বোলাজার

খাঁটি রুবি থেকে রেলগুলির এই পদ্ধতিগুলি ব্যবহার করার জন্য, require "active_support/core_ext/string"পর্যাপ্ত পরিমাণে সরবরাহ করা হচ্ছে, সরবরাহগুলি ইতিমধ্যে ইনস্টল করা আছে।
মাসা সাকানো

120

এটা কেমন?

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

এখানে মন্তব্যে পাওয়া গেছে: একটি রুবি স্ট্রিংকে শ্রেণিবদ্ধ করুন

ওয়েন কনরাডের মন্তব্য দেখুন


10
আপনি দুর্দান্ত, আপনাকে ধন্যবাদ। আমি এই ছোট একটি কাজের জন্য রেল লাইব্রেরিগুলি অন্তর্ভুক্ত করতে চাইনি। এটা সুন্দর. :)
গেরি

11
এটি প্রশ্নের একমাত্র আসল উত্তর। রেল লাইব্রেরি ব্যবহার না করা।
লুইস অরতেগা অরণেদা

40

আপনি যদি রেল ব্যবহার করেন তবে ব্যবহার করুন classify। এটি প্রান্তের কেসগুলি ভালভাবে পরিচালনা করে।

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

বিঃদ্রঃ:

এই উত্তরটি প্রশ্নের বর্ণনার সাথে সুনির্দিষ্ট (এটি প্রশ্নের শিরোনামের সাথে নির্দিষ্ট নয়)। যদি কেউ একটি স্ট্রিংকে উটের ক্ষেত্রে রূপান্তর করতে চাইছে তবে তাদের উচিত সার্জিওর উত্তরটি ব্যবহার করা উচিত । প্রশ্নকর্তা বলেছেন যে সে রূপান্তর app_userকরতে চায় AppUser(না App_user), সুতরাং এই উত্তরটি ..


4
রেল পরিবেশের জন্য, এটি নিখুঁত।
ghayes

নোট করুন যে classifyএকটি স্ট্রিং দেয়, আপনাকে constantizeএটির পরে একটি প্রকৃত শ্রেণিতে রূপান্তর করতে কল করতে হবে।
স্টিফান

1
এর সাথে একটি গুরুত্বপূর্ণ classify'age_in_years'.classifyAgeInYear
সতর্কতা হ'ল বহুবচনযুক্ত

@ br3nt এটি অ্যাক্টিভরকর্ডের পরে বহুবচন হয় না4.2.11
ইউলিস বিএন

23

সূত্র: http://rubydoc.info/gems/extlib/0.9.15/ স্ট্রিং # ক্যামেল_কেস- ইনস্ট্যান্স_মোথড

শেখার উদ্দেশ্যে:

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"

6
@ পিগার্ডিরিও যদি চাকাটিকে অ্যাক্টিভসপোর্ট বলা হয় তবে দয়া করে এটি পুনরায় উদ্ভাবন করুন।
shime

আমি মনে করি লোয়ারকেস ভেরিয়েন্টটি ভুল। ইনজেকশন ব্লকটি সরাসরি self.split('_').inject([]){ |buffer,e| buffer + [buffer.empty? ? e : e.capitalize] }.join
বাফারটিকে

19

খাঁটি রুবি সমাধানের জন্য মানদণ্ড

খাঁটি রুবি কোড দিয়ে এটি করার জন্য আমার মনে যে সমস্ত সম্ভাবনা ছিল আমি তা নিয়েছিলাম, সেগুলি এখানে:

  • মূলধন এবং gsub

    'app_user'.capitalize.gsub(/_(\w)/){$1.upcase}
  • &শর্টহ্যান্ড ব্যবহার করে বিভক্ত এবং মানচিত্র ( ব্যবহারকারী 3869936 এর উত্তরের জন্য ধন্যবাদ)

    'app_user'.split('_').map(&:capitalize).join
  • বিভক্ত এবং মানচিত্র (মিঃ ব্ল্যাক এর উত্তর ধন্যবাদ)

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

এবং এইগুলির জন্য এখানে বেঞ্চমার্ক রয়েছে, আমরা দেখতে পাচ্ছি যে জিএসব এর জন্য বেশ খারাপ। আমি 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)

11

আমি এখানে আপনার প্রশ্নের বিপরীত সন্ধান করছি, উটের ক্ষেত্রে থেকে সাপের ক্ষেত্রে যাচ্ছি to এর জন্য আন্ডারস্কোর ব্যবহার করুন (ডেসমেলাইজ করা হবে না):

AppUser.name.underscore # => "app_user"

বা, আপনার যদি ইতিমধ্যে একটি উটের কেস স্ট্রিং থাকে:

"AppUser".underscore # => "app_user"

বা, আপনি যদি টেবিলের নাম পেতে চান তবে সম্ভবত এই কারণেই আপনি সাপের ঘটনাটি চান:

AppUser.name.tableize # => "app_users"


কেন ব্যবহার করছেন না AppUser.table_name? আপনি যদি অ্যাপ_উজারস না ​​হন তবে সত্যিকারের টেবিলের নামটি অন্য কোথাও সংজ্ঞায়িত করাও নিশ্চিত করবেন।
ইউলিস বিএন

3

এখানে আরও উত্তর যুক্ত করতে আমি কিছুটা অস্বস্তি বোধ করছি। @ ইউলিসি-বিএন থেকে সুন্দর মানদণ্ডকে উপেক্ষা করে সর্বাধিক পঠনযোগ্য এবং নূন্যতম খাঁটি রুবি পদ্ধতির দিকে যাওয়ার সিদ্ধান্ত নিয়েছে। যদিও :classমোড @ 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"

1
উটের কেস আসলে প্রথমে কম। অন্যথায় এটির নামকরণ করা হয়েছে পাস্কেলকেস (বা কখনও কখনও আপার উটের ক্ষেত্রে)। যদিও এই প্রশ্নে এটি অস্পষ্ট!
ইউলিস বিএন

2
@ ইউলিসিবিএন, টিবিএইচ আমি শব্দের ইতিহাসে নেই। উইকিপিডিয়া দাবি PascalCaseএকটি সাবসেট CamelCase। এছাড়াও এটি আমি জানতাম - উটের মামলাটি উভয়ের ক্ষেত্রেই প্রযোজ্য। তবে আমি কখনও তদন্ত করিনি। যদিও পাস্কেলকেস উল্লেখ করার জন্য ধন্যবাদ। en.wikipedia.org/wiki/Camel_case
akostadinov

2
এটি ইমো পৃষ্ঠায় সেরা উত্তর। এটি চমৎকার হবে যদি হতো :methodসংস্করণ একটি করেনি downcaseপ্রথম তাই এটি উভয় ব্যবহার করা যেতে পারে lower_snake_caseএবং UPPER_SNAKE_CASE
স্কেজেডাল

0

এখানে তালিকাভুক্ত অন্যান্য পদ্ধতিগুলির বেশিরভাগই রেয়েল নির্দিষ্ট। আপনি যদি খাঁটি রুবির সাথে এটি করতে চান তবে নীচেরটি হ'ল আমি সর্বাধিক সংক্ষিপ্ত ভাবে এলাম (প্রস্তাবিত উন্নতির জন্য @ ইউলিসি-বিএনকে ধন্যবাদ জানাই)

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

আপনার "উটের কেস" এর সংজ্ঞাটি খুব সীমাবদ্ধ। জাভা, রুবি মধ্যে ক্লাস নাম, উদাহরণস্বরূপ, হয় উট ক্ষেত্রে MyFavoriteClass ... কিন্তু তারা একটি নিম্ন cased প্রাথমিক চিঠি হবে না। কখনও কখনও উটের ক্ষেত্রে প্রাথমিক ক্যাপ থাকে। কখনও কখনও এটি না।
মাসুকোমি

আপনি কেবলমাত্র একটি ব্যবহার করতে পারবেন সেখানে 2 রিজেক্স ব্যবহার ওভারকিল। আপনি কেবল নন ক্যাপচারিং গ্রুপ ব্যবহার করতে পারেন:x.gsub(/(?:_|^)(\w)/){$1.upcase}
ইউলিস বিএন

@ ইউলিসিবিএন, এবং আমরা আপনার gsubসমাধানে ফিরে এসেছি বলে মনে হচ্ছে এটি mapসমাধানের তুলনায় ধীর is
akostadinov

0

স্ট্রিংকে ক্যামেলাইজ যুক্ত করতে প্রসারিত করুন

খাঁটি রুবিতে আপনি রেলগুলি থেকে সঠিক কোড ব্যবহার করে স্ট্রিং ক্লাস প্রসারিত করতে পারেন .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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.