রুবিতে সংস্করণগুলি কীভাবে তুলনা করবেন?


119

কিছু সংস্করণ স্ট্রিং তুলনা করতে এবং নতুন পেতে কীভাবে কোনও টুকরো কোড লিখবেন?

উদাহরণ হিসেবে বলা যায় স্ট্রিং পছন্দ: '0.1', '0.2.1', '0.44'


আমার কিছুটা আগে হতাশাবাদী সংস্করণের তুলনা করা দরকার, তবে আমি এটি করতে রুবিগেমসের উপর নির্ভর করতে চাইনি, তাই আমি একটি সাধারণ Versionক্লাস লিখেছিলাম যা আমার যা প্রয়োজন সবকিছু করে: shouts.jeffkreeftmeijer.com/2014/…
jkreeftmeijer

উত্তর:


230
Gem::Version.new('0.4.1') > Gem::Version.new('0.10.1')

14
Gem::Version...সিনট্যাক্স আমাকে ভাবলাম একটি মণি ইনস্টল করতে হবে প্রণীত। তবে এটির প্রয়োজন ছিল না।
গিলিয়াম

দ্রষ্টব্য: এটি রুবি ১.x এ আমার জন্য অপরিজ্ঞাত পরিবর্তনশীল 'মণি' সম্পর্কে ত্রুটি দেয় তবে রুবি ২.x তে প্রত্যাশা অনুযায়ী কাজ করে। আমার ক্ষেত্রে আমি রুবি ১.x (২.x নয়) হওয়ার বিপরীতে রুবি_ভেরিশনটি যাচাই করছিলাম, তাই আমি জন হিল্যান্ড এবং ডিজিটালরোসের মতো কেবল রুবি_ভিভারশন.স্প্লিট ('।') [0] = "" 1 করলাম।
uliwitness

5
Gem::Dependency.new(nil, '~> 1.4.5').match?(nil, '1.4.6beta4')
লেভিনেলেক্স

6
@ সাক্ষী এটি রুবি 1.x বনাম 2.x নয়; এটি 1.8.x বনাম 1.9+। 1.8.x এর মাধ্যমে রুবি ডিফল্টরূপে রুবিজেমগুলি অন্তর্ভুক্ত করে না; নেমস্পেসে require 'rubygems'অ্যাক্সেস পেতে আপনার একটি দরকার Gem। 1.9 থেকে, তবে এটি স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত।
মার্ক রিড

এটি ওয়াইল্ডকার্ড এনপিএম সংস্করণগুলির তুলনা করার জন্য কাজ করেছে। +1
গভীরতরতর

35

আপনার যদি হতাশাবাদী সংস্করণের সীমাবদ্ধতাগুলি পরীক্ষা করতে হয় তবে আপনি মণি :: নির্ভরতা ব্যবহার করতে পারেন :

Gem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')

1
নতুন সংস্করণগুলিতে নামের জন্য একটি স্ট্রিং প্রয়োজন বলে মনে হচ্ছে। একটি খালি স্ট্রিং সূক্ষ্মভাবে কাজ করে, যেমনGem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')
পিটার ওয়াগনেট

19
class Version < Array
  def initialize s
    super(s.split('.').map { |e| e.to_i })
  end
  def < x
    (self <=> x) < 0
  end
  def > x
    (self <=> x) > 0
  end
  def == x
    (self <=> x) == 0
  end
end
p [Version.new('1.2') < Version.new('1.2.1')]
p [Version.new('1.2') < Version.new('1.10.1')]

3
অন্যান্য উত্তরগুলির মতো এখানেও দেখে মনে হচ্ছে আপনি সংখ্যার পরিবর্তে স্ট্রিং তুলনা করছেন যা '0.10' এবং '0.4' এর মতো সংস্করণগুলির তুলনা করার সময় সমস্যা তৈরি করবে।
জন হিল্যান্ড

7
সংক্ষিপ্ত সমাধানের জন্য উত্সাহিত যার জন্য কোনও রত্ন ইনস্টল করার প্রয়োজন নেই।
জেডি।

2
এটির মূল্যের জন্য: vers = (1..3000000).map{|x| "0.0.#{x}"}; 'ok' puts Time.now; vers.map{|v| ComparableVersion.new(v) }.sort.first; puts Time.now # 24 seconds 2013-10-29 13:36:09 -0700 2013-10-29 13:36:33 -0700 => nil puts Time.now; vers.map{|v| Gem::Version.new(v) }.sort.first; puts Time.now # 41 seconds 2013-10-29 13:36:53 -0700 2013-10-29 13:37:34 -0700 কোড ব্লব এটিকে কুৎসিত করে তুলছে, তবে মূলত, এই বনাম রত্ন :: সংস্করণটি প্রায় দ্বিগুণ দ্রুত গতিতে ব্যবহার করা হচ্ছে।
শাই

যদিও একটি সংস্করণ অ্যারে নয়
সেরজিও টুলেন্টেসেভ

15

আপনি Versionomyরত্নটি ব্যবহার করতে পারেন ( গিথুবে উপলভ্য ):

require 'versionomy'

v1 = Versionomy.parse('0.1')
v2 = Versionomy.parse('0.2.1')
v3 = Versionomy.parse('0.44')

v1 < v2  # => true
v2 < v3  # => true

v1 > v2  # => false
v2 > v3  # => false

4
আমি এটি দেখেছি, তবে সত্যিই একটি সহজ জিনিস করার জন্য আমার 2 টি রত্ন ব্যবহার করা প্রয়োজন। আমি এটি শেষ পছন্দ হিসাবে ব্যবহার করতে চাই।
ব্যবহারকারী 239895

8
"চাকা পুনরায় উদ্ভাবন করবেন না"। কারণ এটি সহজ এটির অর্থ এই নয় যে প্রোগ্রামার এতে কাজ এবং চিন্তাভাবনা রাখেনি। রত্নটি ব্যবহার করুন, কোডটি পড়ুন এবং এ থেকে শিখুন - এবং আরও বড় এবং আরও ভাল জিনিসগুলিতে এগিয়ে যান!
ট্র্যাভোক

নির্ভরতা পরিচালনা এবং সংস্করণ রক্ষণাবেক্ষণ একটি কঠিন সমস্যা, সম্ভবত 2 সংস্করণ তুলনা করার কাজটির চেয়ে অনেক বেশি কঠিন difficult আমি পুরোপুরি একমত যে আরও 2 টি নির্ভরতা প্রবর্তন করা এক্ষেত্রে একটি শেষ অবলম্বন হওয়া উচিত।
kkodev

10

আমি করবো

a1 = v1.split('.').map{|s|s.to_i}
a2 = v2.split('.').map{|s|s.to_i}

তাহলে আপনি করতে পারেন

a1 <=> a2

(এবং সম্ভবত অন্যান্য সমস্ত "সাধারণ" তুলনা)।

... এবং যদি আপনি একটি <বা >পরীক্ষা চান , আপনি উদাহরণস্বরূপ করতে পারেন

(a1 <=> a2) < 0

বা আপনি যদি তেমন ঝোঁক থাকেন তবে আরও কিছু ফাংশন মোড়ানো করুন।


1
অ্যারে.ক্লাস_ইভাল Comp তুলনীয় অন্তর্ভুক্ত করে all সমস্ত অ্যারে <,> ইত্যাদি ইত্যাদিতে প্রতিক্রিয়া তৈরি করবে বা আপনি যদি কিছু নির্দিষ্ট অ্যারেতে কেবল এটি করতে চান: a = [1, 2]; a.extend (তুলনীয়)
ওয়েন কনরাড

4
এই সমাধানটির সাথে আমি যে সমস্যাটি পেয়েছি তা হ'ল এটি আবার "1.2.0" "" 1.2 "এর চেয়ে বড়
মারিয়া এস

9

Gem::Version এখানে যাওয়ার সহজ উপায়:

%w<0.1 0.2.1 0.44>.map {|v| Gem::Version.new v}.max.to_s
=> "0.44"

সংস্করণের চেয়ে অনেক বেশি উন্নত যার জন্য সি-এক্সটেনশন প্রয়োজন !?
ডাব্লু। অ্যান্ড্রু লো তৃতীয়

আমি 'সর্বোচ্চ' কাজ করবে বলে মনে করি না .. এটি ০.৪৪ এর বেশি হতে হবে বলে প্রতিবেদন করবে। যা সেমভার সংস্করণগুলির সাথে তুলনা করার সময় সত্য নয়।
ফ্লো উও

2
এটি সর্বশেষ রত্ন :: সংস্করণে স্থির করা হয়েছে বলে মনে হয়। 0.44 সঠিকভাবে এখন 0.5 এর চেয়ে বেশি হিসাবে রিপোর্ট করা হয়েছে।
ফ্লো উও

5

যদি আপনি কোনও রত্ন ব্যবহার না করে হাত দিয়ে এটি করতে চান তবে নীচের মতো কিছু কাজ করা উচিত, যদিও এটি কিছুটা অবনমিত দেখাচ্ছে।

versions = [ '0.10', '0.2.1', '0.4' ]
versions.map{ |v| (v.split '.').collect(&:to_i) }.max.join '.'

মূলত, আপনি প্রতিটি সংস্করণ স্ট্রিংকে পূর্ণসংখ্যার অ্যারেতে পরিণত করেন এবং তারপরে অ্যারের তুলনা অপারেটরটি ব্যবহার করেন । আপনি যদি কোডটিতে চলেছেন তবে কারওর বজায় রাখতে হবে এমন কিছু অনুসরণ করার জন্য উপাদানটির পদক্ষেপগুলি ছিন্ন করতে পারেন।


-1

আমার একই সমস্যা ছিল, আমি একটি রত্ন-কম সংস্করণ তুলনামূলক চেয়েছিলাম, এটি নিয়ে এসেছিল:

def compare_versions(versionString1,versionString2)
    v1 = versionString1.split('.').collect(&:to_i)
    v2 = versionString2.split('.').collect(&:to_i)
    #pad with zeroes so they're the same length
    while v1.length < v2.length
        v1.push(0)
    end
    while v2.length < v1.length
        v2.push(0)
    end
    for pair in v1.zip(v2)
        diff = pair[0] - pair[1]
        return diff if diff != 0
    end
    return 0
end
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.