<=> विभिन्न सॉर्टिंग रणनीतियों के लिए कैसे काम करता है?

मैं CodeAcademy पर कुछ ट्यूटोरियल के माध्यम से जा रहा हूं, और इस परिदृश्य में आया:

books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]

# To sort our books in ascending order, in-place
books.sort! { |firstBook, secondBook| firstBook <=> secondBook }


# Sort your books in descending order, in-place below
# this lin initially left blank
books.sort! {|firstBook, secondBook| secondBook <=> firstBook}

Instead of using if/else blocks, I gave this a shot, and it worked, but I don't know why. I assume it doesn't matter which order you place the items in the check (i.e., a <=> b vs. b <=> a). Could someone explain what's happening here?

3
मैं वास्तव में याद नहीं कर सकता - यह सिर्फ व्यक्तिगत वरीयता है। मैं चर नामों में _ देखने वास्तव में नापसंद।
जोड़ा लेखक MrDuk, स्रोत
मैं होप रूबी के लिए एक ट्यूटोरियल सुझाव नहीं दिया था कि आप अपने चर के लिए camelCase का उपयोग करें। रूबी में हम चर के लिए सांप_case का उपयोग करते हैं।
जोड़ा लेखक the Tin Man, स्रोत
यदि आप वस्तुओं को उलट देते हैं तो सॉर्टिंग अवरोही और आरोही जैसे ऑर्डर को बदल देती है
जोड़ा लेखक uday, स्रोत

3 उत्तर

If you reverse the elements in <=> you reverse its value. If the elements are equal this operator returns 0, but if the first one is smaller it returns a negative value, if the first is greater it returns a positive value. Thus if temp = a <=> b then b <=> a is -temp. So you reverse the order of sorting if you write the arguments in reverse order.

5
जोड़ा
धन्यवाद, लेकिन मैं अभी भी थोड़ा उलझन में हूं - शायद मेरा प्रश्न होना चाहिए था, -1 बनाम 1 का महत्व क्या है? मुझे लगता है कि -1 वस्तु से कम है और 1 बड़ा है, लेकिन सॉर्टिंग रणनीति उस मूल्य को कैसे संभालने के बाद संभालती है?
जोड़ा लेखक MrDuk, स्रोत
@ctote यदि आप उलझन में हैं, तो इसका उपयोग न करने का प्रयास करें, और इसके बजाय sort_by! का उपयोग करें, जो श्वार्टज़ियन रूपांतरण का उपयोग करता है। यह समझना आसान है, और अधिक कुशल है। अवरोही क्रम रिवर्स द्वारा प्राप्त किया जा सकता है। sort! का उपयोग करने के लिए बहुत अधिक कारण नहीं है।
जोड़ा लेखक sawa, स्रोत
@ctote कल्पना करें कि आपके पास एक सॉर्टिंग एल्गोरिदम है जो कुछ करता है यदि a b से कम है। यदि आप इस ऑपरेटर के तर्कों के क्रम को उलट देते हैं तो एल्गोरिदम एक ही ऑपरेशन करेगा, लेकिन a की इसकी धारणा b से कम हो जाएगी। इसलिए जब भी पहले कोड में a b से कम था, तो यह दूसरे में अधिक हो जाएगा। एक साधारण बबल प्रकार को आज़माएं और लिखें। क्या होगा यदि आपकी तुलना a को उलट दिया गया है यानी iFe सही है iff a> b
जोड़ा लेखक Ivaylo Strandjev, स्रोत
@cote तथाकथित स्पेसशिप-ऑपरेटर <=> मौलिक तुलनित्र है। इसका उपयोग यह निर्धारित करने के लिए किया जाता है कि किस तरह के क्रम में दो तत्वों के सापेक्ष होना चाहिए। यदि -1 तो पहले दूसरे से पहले आता है, यदि 1 तो पहला दूसरा के बाद आता है। यदि 0 उन्हें सॉर्टिंग परिप्रेक्ष्य से बिल्कुल समान माना जाता है और कोई ऑर्डरिंग लागू नहीं होती है।
जोड़ा लेखक tadman, स्रोत
जटिल वस्तुओं को सॉर्ट करते समय sort_by अधिक कुशल है। तारों और पूर्णांक की तरह सरल ऑब्जेक्ट्स sort का उपयोग करके तेज़ी से होंगे। ऐसा इसलिए है क्योंकि Schwartzian रूपांतरण करने के लिए sort_by ओवरहेड है। यह विधि नाम से मुखौटा है, लेकिन अंतर्निहित कोड को देखें और आप सॉर्ट किए गए तत्वों के सेट-अप और आंसू-डाउन को देखेंगे, इसके साथ जुड़ी लागत है।
जोड़ा लेखक the Tin Man, स्रोत

Here's some simple visual ways of seeing what <=> does, and how reversing the order of the comparison variables affects the order of the output.

एक मूल ऐरे से शुरू करना:

foo = %w[a z b x]

हम आरोही क्रमबद्ध कर सकते हैं:

foo.sort { |i, j| i <=> j } # => ["a", "b", "x", "z"]

या तुलना की जा रही दो चरों को उलटकर एक अवरोही क्रम:

foo.sort { |i, j| j <=> i } # => ["z", "x", "b", "a"]

The <=> operator returns -1, 0 or 1, depending on whether the comparison is <, == or > respectively.

हम तुलना के परिणाम को नकारकर इसका परीक्षण कर सकते हैं, जो सिद्धांत सत्य होने पर आदेश को उलट देगा।

foo.sort { |i, j| -(i <=> j) } # => ["z", "x", "b", "a"]
foo.sort { |i, j| -(j <=> i) } # => ["a", "b", "x", "z"]

तुलना के परिणाम को अस्वीकार कर ऑर्डर रिवर्स करता है। लेकिन, कोड में स्पष्टता के लिए, चर के क्रम को उलट दें।

That all said, using sort, or its destructive sibling sort!, isn't always the fastest way to sort complex objects. Simple objects, like strings and characters, and numerics, sort extremely quickly because their classes implement the necessary methods to perform <=> tests quickly.

कुछ उत्तरों और टिप्पणियों का उल्लेख sort_by है, तो चलिए वहां जाएं।

कॉम्प्लेक्स ऑब्जेक्ट्स आमतौर पर सही ढंग से क्रमबद्ध नहीं होते हैं, इसलिए हम गेटर्स/एक्सेसर्स का उपयोग करके कुछ मूल्य प्राप्त करने के लिए समाप्त होते हैं, जिसे हम तुलना करना चाहते हैं, और उस कार्रवाई के लिए CPU समय में लागत होती है। sort बार-बार मानों की तुलना करता है ताकि पुनर्प्राप्ति बार-बार हो, और सॉर्टिंग नहीं होने पर बर्बाद समय के रूप में जोड़ें।

इसे ठीक करने के लिए, पर्ल दुनिया में एक प्रमुख खिलाड़ी रैंडल श्वार्टज़ नामक एक स्मार्ट लड़के ने एक एल्गोरिदम का उपयोग शुरू किया जो एक बार मूल्य को क्रमबद्ध करने के लिए उपयोग किया जाता है; परिणामस्वरूप एल्गोरिदम को आमतौर पर Schwartzian Transform कहा जाता है। वह मान, और वास्तविक वस्तु, एक छोटे उप-सरणी में एक साथ बंडल की जाती है, और उसके बाद क्रमबद्ध होती है। चूंकि सॉर्ट प्री-कंप्यूटेड वैल्यू के खिलाफ होता है, यह, और इसके संबंधित ऑब्जेक्ट को ऑर्डरिंग में चारों ओर ले जाया जाता है, जब तक कि सॉर्ट पूरा नहीं हो जाता है। उस बिंदु पर, वास्तविक वस्तुओं को पुनर्प्राप्त किया जाता है और विधि के परिणामस्वरूप वापस कर दिया जाता है। रुबी उस प्रकार का प्रकार लागू करता है जो sort_by

sort_by doesn't use <=> externally, so you can sort by simply telling it how to get at the value you want to compare against:

class Foo
  attr_reader :i, :c
  def initialize(i, c)
    @i = i
    @c = c
  end
end

वस्तुओं की सरणी यहाँ है। ध्यान दें कि वे बनाए गए क्रम में हैं, लेकिन क्रमबद्ध नहीं हैं:

foo = [[1,  'z'], [26, 'a'], [2,  'x'], [25, 'b'] ].map { |i, c| Foo.new(i, c) }
# => [#,
#     #,
#     #,
#     #]

Sorting them by the integer value:

foo.sort_by{ |f| f.i } 
# => [#,
#     #,
#     #,
#     #]

Sorting them by the character value:

foo.sort_by{ |f| f.c } 
# => [#,
#     #,
#     #,
#     #]

sort_by doesn't respond as well to using a negated value as sort and <=>, so, based on some benchmarks done a while back on Stack Overflow, we know that using reverse on the resulting value is the fastest way to switch the order from ascending to descending:

foo.sort_by{ |f| f.i }.reverse
# => [#,
#     #,
#     #,
#     #]

foo.sort_by{ |f| f.c }.reverse 
# => [#,
#     #,
#     #,
#     #]

They're somewhat interchangable, but you have to remember that sort_by does have overhead, which is apparent when you compare its times against sort times when running against simple objects. Use the right method at the right time and you can see dramatic speed-ups.

3
जोड़ा

इसे स्पेसशिप ऑपरेटर कहा जाता है

यदि आपके पास ऐसा कुछ है

my_array = ["b", "c", "a"]

my_array.sort! does the compare the elements of the array since it knows that the letters of english alphabet have natural ordering, likewise if you have array of integers

my_array2 = [3,1,2]

my_array2.sort! will compare the elements and gives the result as [1,2,3]

but if you want to change how the comparison is made in an array of strings or complex objects you specify it using the <=> operator..

my_array3 = ["हैलो", "दुनिया कैसे हैं", "आप"]

my_array3.sort! { |first_element, second_element| first_element <=> second_element }

तो यह इस तरह की तुलना करने के लिए सॉर्ट विधि बताएगा:

Is first_element < second_element?

first_element = second_element है?

Is first_element > second_element?

लेकिन अगर आप इस stmt ले,

my_array3.sort! { |first_element, second_element| first_element <=> second_element }

तुलना निम्नानुसार की जाती है:

Is second_element < first_element?

Second_element = first_element है?

Is second_element > first_element?

इसलिए यदि आप तत्वों को विचार करने के लिए बदलते हैं तो इससे कोई फर्क पड़ता है।

0
जोड़ा
यह आमतौर पर "स्पेस-शिप ऑपरेटर" कहा जाता है। यह हमेशा पर्ल में एक बाइनरी-तुलना ऑपरेटर है, जहां रूबी ने इसे विरासत में मिला है।
जोड़ा लेखक the Tin Man, स्रोत
इसके अलावा, रूबे में चर के लिए camelCase नहीं, snake_case का उपयोग करें। और, आपके उदाहरण काम नहीं करते हैं। first_element और second_element का उपयोग करें और सुनिश्चित करें कि आपके असाइनमेंट और वेरिएबल वर्तनी सुसंगत हैं। अपने उदाहरणों का परीक्षण करने के लिए आईआरबी का उपयोग करना एक अच्छा विचार है, और उसके बाद काम करने के बाद उन्हें कॉपी और पेस्ट करें।
जोड़ा लेखक the Tin Man, स्रोत
"... तारों या जटिल वस्तुओं की एक सरणी तो यह नहीं जानता कि उन वस्तुओं की तुलना कैसे करें"? रुबी जानता है कि तारों की तुलना कैसे करें जैसे कि यह एकल वर्ण करता है, जो तार हैं। % w [foo bar] .sort # => ["bar", "foo"]
जोड़ा लेखक the Tin Man, स्रोत
@theTinMan, धन्यवाद सुधार किया! :) और परीक्षण: डी
जोड़ा लेखक uday, स्रोत