रूबी <=> (स्पेसशिप) ऑपरेटर क्या है?


262

रूबी <=>(स्पेसशिप) ऑपरेटर क्या है? क्या ऑपरेटर किसी अन्य भाषाओं द्वारा कार्यान्वित किया जाता है?


1
अब सरणियों की तुलना करने के बारे में क्या? इस पुस्तक में कहा गया है "तत्व की तुलना तत्व से करता है, रिटर्न 0 अगर बराबर, -1 अगर कम, 1 अधिक हो तो, लेकिन क्या [1,3,2] <=> [2,2,2]?
एसएफ।

3
@ एसएफ, जब लोग सरणियों की तुलना करते हैं, तो उनका मतलब आमतौर पर तुलनात्मक रूप से तुलना करना होता है (जैसे एक शब्दकोष में, यानी [1,3,2] <[2,2,2] क्योंकि पहले तत्व अलग होते हैं)। शायद ही (माटलब में फ़े) सरणी तुलना प्रति तत्व परिणामों की एक सरणी देता है; इस स्थिति में: [-1, 1, 0]।
लियोरी

ध्यान दें कि Arrays जिसमें nil तत्व होते हैं वे तुलनीय हैं यदि किसी भी nil से पहले वाले तत्व अलग हैं, और तुलनीय नहीं तो nil-non-nil के साथ तुलना की जानी चाहिए। Ie [1, nil] <=> [2, 3] => -1, लेकिन [1, nil] <=> [1, 3] => nil। यह बेकार है, मूल रूप से।
क्लिफर्डहार्ट

जब एल्गोरिथ्म की संगति के कारण [1,nil] <=> [1,3]आप जैसे सरणियों की तुलना करते हैं, तो परिणाम नहीं nilहोने तक प्रत्येक तत्व की तुलना करें । रूबी के पास इस उदाहरण में कम-से-अधिक या अधिक-से-अधिक घोषणा करने का कोई तरीका नहीं है, क्योंकि एक तुलना बस नहीं की जा सकती है। के रूप में "बराबर नहीं" व्यवहार किया जाना चाहिए। यदि आप डेटा के बारे में कुछ जानते हैं, और उदाहरण के लिए , रूबी के रूप में इलाज करना चाहते हैं । <=>0nilnil0
lilole

जवाबों:


359

पर्ल संभवतः इसका उपयोग करने वाली पहली भाषा थी। ग्रूवी एक और भाषा है जो इसका समर्थन करती है। मूल रूप से बजाय लौटने का 1( true) या 0( false) क्या तर्क समान या असमान हैं पर निर्भर करता है, अंतरिक्ष यान ऑपरेटर वापस आ जाएगी 1, 0या −1सही तर्क के लिए छोड़ दिया तर्क रिश्तेदार के मूल्य पर निर्भर करता है।

a <=> b :=
  if a < b then return -1
  if a = b then return  0
  if a > b then return  1
  if a and b are not comparable then return nil

यह एक सरणी को छाँटने के लिए उपयोगी है।


27
बिल्कुल सही। मुझे लगता है कि यह जावा की तुलना के एक बहुत ही सुंदर संस्करण के रूप में है।
माइक रीडेल

12
c # में एनालॉग है IComparable.CompareTo
सर्गेई मर्वोडा

1
वास्तव में मुझे लगता है कि किसी भी नकारात्मक या सकारात्मक मूल्य को वापस किया जा सकता है। 0 का मतलब अभी भी समानता है।
सुपरल्यूमरी

1
@superluminary C के स्ट्रैम्प फंक्शन के विपरीत, x <=> y ​​को विशेष रूप से केवल -1, 0, 1, या nil के लिए डिज़ाइन किया गया है यदि x और y तुलनीय नहीं हैं (रूबी और इसे उपयोग करने वाली अन्य भाषाओं में)। इससे ऑपरेटर को ओवरलोड करना आसान हो जाता है, जैसे कि रूबी के तुलनात्मक मिश्रण के लिए। पर्ल में, जहां ऑपरेटर सबसे अधिक संभावना उत्पन्न करता था, इसका उपयोग मुख्य रूप से "सॉर्ट ब्लॉक लिस्ट" सिंटैक्स को सरल बनाने के लिए किया गया था। BLOCK एक सबरूटीन है जो किसी भी सकारात्मक संख्या, ऋणात्मक संख्या, या 0 को वापस कर सकता है जो इस बात पर निर्भर करता है कि सूची आइटम को कैसे सॉर्ट किया जाना चाहिए। स्पेसशिप ऑपरेटर ब्लॉक में उपयोग करने के लिए सुविधाजनक है।
टोनीअरा

2
ध्यान दें कि यदि दो वस्तुओं की तुलना में तुलना नहीं कर रहे हैं, यदि आप एक नहीं के बराबर मिलता है
Gamov

70

जब आप इसे अपनी कक्षा में परिभाषित करते हैं और तुलनात्मक मॉड्यूल शामिल करते हैं तो स्पेसशिप विधि उपयोगी होती है । आपकी कक्षा को फिर >, < , >=, <=, ==, and between?मुफ्त में विधियाँ मिलती हैं।

class Card
  include Comparable
  attr_reader :value

  def initialize(value)
    @value = value
  end

  def <=> (other) #1 if self>other; 0 if self==other; -1 if self<other
    self.value <=> other.value
  end

end

a = Card.new(7)
b = Card.new(10)
c = Card.new(8)

puts a > b # false
puts c.between?(a,b) # true

# Array#sort uses <=> :
p [a,b,c].sort # [#<Card:0x0000000242d298 @value=7>, #<Card:0x0000000242d248 @value=8>, #<Card:0x0000000242d270 @value=10>]

20

यह एक सामान्य तुलना ऑपरेटर है। यह या तो -1, 0, या +1 पर निर्भर करता है कि उसका रिसीवर उसके तर्क से कम, बराबर या उससे अधिक है या नहीं।


18

मैं सरल उदाहरण के साथ समझाऊंगा

  1. [1,3,2] <=> [2,2,2]

    रूबी बाएं हाथ की ओर से दोनों सरणी के प्रत्येक तत्व की तुलना करना शुरू कर देगी। 1बाएं सरणी 2के लिए दायां सरणी से छोटा है । इसलिए बायां सरणी दाएं सरणी से छोटा है। आउटपुट होगा -1

  2. [2,3,2] <=> [2,2,2]

    ऊपर के रूप में यह पहले तत्व की तुलना करेगा जो समान हैं फिर यह दूसरे तत्व की तुलना करेगा, इस मामले में बाएं सरणी का दूसरा तत्व अधिक है इसलिए आउटपुट है 1


क्या यह प्रत्येक सरणी के पहले बाएं तत्व की तुलना करता है या अन्य तत्वों की तुलना करना जारी रखता है? अच्छा स्पष्टीकरण
लात Buttowski

1
@KickButtowski यह अन्य तत्वों की तुलना करना जारी रखता है जब तक कि यह एक असमान संख्या नहीं पाता है।
अनिल मौर्य

5

चूंकि यह ऑपरेटर एक पूर्णांक अभिव्यक्ति की तुलना को कम करता है, यह कई कॉलम / विशेषताओं के आधार पर आरोही या अवरोही को सॉर्ट करने का सबसे सामान्य उद्देश्य तरीका प्रदान करता है।

उदाहरण के लिए, अगर मेरे पास वस्तुओं की एक सरणी है तो मैं इस तरह की चीजें कर सकता हूं:

# `sort!` modifies array in place, avoids duplicating if it's large...

# Sort by zip code, ascending
my_objects.sort! { |a, b| a.zip <=> b.zip }

# Sort by zip code, descending
my_objects.sort! { |a, b| b.zip <=> a.zip }
# ...same as...
my_objects.sort! { |a, b| -1 * (a.zip <=> b.zip) }

# Sort by last name, then first
my_objects.sort! { |a, b| 2 * (a.last <=> b.last) + (a.first <=> b.first) }

# Sort by zip, then age descending, then last name, then first
# [Notice powers of 2 make it work for > 2 columns.]
my_objects.sort! do |a, b|
      8 * (a.zip   <=> b.zip) +
     -4 * (a.age   <=> b.age) +
      2 * (a.last  <=> b.last) +
          (a.first <=> b.first)
end

प्रत्येक आधार पर आरोही / अवरोही के किसी भी क्रमपरिवर्तन में इस बुनियादी पैटर्न को किसी भी संख्या में स्तंभों के आधार पर क्रमबद्ध किया जा सकता है।


अच्छे उदाहरण, बस यह कि आखिरी उम्मीद के मुताबिक काम नहीं करता है। कारकों में अवरोही क्रम में दो की शक्तियां होनी चाहिए, अर्थात 8, -4, 2, 1. जिस तरह से आपने इसे लिखा है (कारकों 4, -3,2,1 के साथ), उदाहरण के लिए "आयु + lastname" "ज़िप" से अधिक मायने रखता है "...
एल्मर जैंडर

मुझे नहीं लगता कि उन संख्याओं का मतलब है कि आपको लगता है कि उनका क्या मतलब है। प्रत्येक कारक साइनम को गुणा करता है, जो -1, 0 या 1 होगा। 2 की शक्तियां यहां कोई मायने नहीं रखती हैं। -3 * (a.age <=> b.age) 3 * के समान ही है (b.age <=> a.age)। परिणाम का संकेत वह है जो इसे asc या desc बनाता है।
lilole

नहीं, यह बहुत मायने रखता है। ज़िप के लिए कारक अन्य सभी कारकों के योग (पूर्ण) से बड़ा होना चाहिए, और उम्र का कारक अंतिम और पहले के कारकों के योग (पूर्ण) से बड़ा होना चाहिए, और इसी तरह। और संख्याओं का सबसे छोटा अनुक्रम जो पूरा करता है वह दो की शक्तियों का अनुक्रम है ... और BTW यदि आप मेरी टिप्पणी को ध्यान से पढ़ते हैं, तो आपने देखा होगा कि मैंने माइनस साइन को शामिल किया है ...
एल्मार जेंडर

1
ठीक है, शायद मैं उस पर थोड़ा और विस्तार करूँगा: कारकों (4, -3,2,1) और अंतरिक्ष यान से परिणाम के साथ (1,1, -1, -1) भारित राशि -2 है, लेकिन इसे सकारात्मक बनाने की जरूरत है! अन्यथा बड़ा ज़िप छोटे ज़िप से पहले आएगा। यह कारकों (8, -4,2,1) के साथ नहीं होगा।
एलमार जेंडर

1
अब मैं देख रहा हूँ, अगर> 2 कॉलमों को छाँटना है तो 2 की शक्तियों की आवश्यकता है। इसे ठीक करने में मदद के लिए धन्यवाद। क्षमा करें, यदि आपकी 3 या अधिक कॉलम छांट गलत हैं।
lilole

-2

क्या है <=> ('स्पेसशिप ऑपरेटर')

ऑपरेटर को पेश करने वाले RFC के अनुसार , $ a <=>$ b

 -  0 if $a == $b
 - -1 if $a < $b
 -  1 if $a > $b

 - Return 0 if values on either side are equal
 - Return 1 if value on the left is greater
 - Return -1 if the value on the right is greater

उदाहरण:

//Comparing Integers

echo 1 <=> 1; //ouputs 0
echo 3 <=> 4; //outputs -1
echo 4 <=> 3; //outputs 1

//String Comparison

echo "x" <=> "x"; // 0
echo "x" <=> "y"; //-1
echo "y" <=> "x"; //1

अधिक:

// Integers
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

// Floats
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1

// Strings
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1

echo "a" <=> "aa"; // -1
echo "zz" <=> "aa"; // 1

// Arrays
echo [] <=> []; // 0
echo [1, 2, 3] <=> [1, 2, 3]; // 0
echo [1, 2, 3] <=> []; // 1
echo [1, 2, 3] <=> [1, 2, 1]; // 1
echo [1, 2, 3] <=> [1, 2, 4]; // -1

// Objects
$a = (object) ["a" => "b"]; 
$b = (object) ["a" => "b"]; 
echo $a <=> $b; // 0
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.