2012-01-13 7 views
13

सॉर्ट नहीं किया गया है मेरे पास सरणी की एक सरणी है जिसे मैं सॉर्ट करना चाहता हूं। सरणी ए का प्रत्येक तत्व 3 तत्वों वाला एक सरणी है। सरणी एक लगता है कि:मैं पर्ल में सरणी सरणी को सॉर्ट करना चाहता हूं, लेकिन परिणाम

my @A = ([2,3,1], [1,2,3], [1,0,2], [3,1,2], [2,2,4]); 

मैं आरोही क्रम में एक तरह से करना चाहते हैं। 2 तत्वों की तुलना करते समय, पहली संख्या का उपयोग किया जाता है। यदि कोई टाई है, तो दूसरी संख्या का उपयोग किया जाता है, और फिर तीसरा नंबर।

मेरा कोड यहां है। मैं 2 तत्वों की तुलना करने के लिए एक फ़ंक्शन 'cmpfunc' का उपयोग करता हूं।

sub cmpfunc { 
    return ($a->[0] <=> $b->[0]) or 
      ($a->[1] <=> $b->[1]) or 
      ($a->[2] <=> $b->[2]); 
} 
my @B = sort cmpfunc @A; 
print "Result:\n"; 
for my $element (@B) { 
    print join(",", @{$element}) . "\n"; 
} 

परिणाम:

1,2,3 
1,0,2 
2,3,1 
2,2,4 
3,1,2 

परिणाम कुछ हद तक हल कर रहा है, लेकिन सही नहीं। मुझे उम्मीद है कि:

1,0,2 
1,2,3 
2,2,4 
2,3,1 
3,1,2 

क्या मेरे तुलनात्मक कार्य में कोई त्रुटि है? अजीब बात यह है कि, जब मैं ब्लॉक में तुलना कोड डालता हूं, तो परिणाम सही तरीके से सॉर्ट किया जाता है।

my @C = sort { ($a->[0] <=> $b->[0]) or 
       ($a->[1] <=> $b->[1]) or 
       ($a->[2] <=> $b->[2]) } @A; 
+0

संबंधित: http://stackoverflow.com/questions/1512547 – mob

उत्तर

21

आप

return ($a->[0] <=> $b->[0]) 

इससे पहले कि यह "या" खंड में से किसी को हो जाता है जो रिटर्न को क्रियान्वित कर रहे हैं।

या तो "वापसी" कीवर्ड निकाल सकते हैं या वापसी के लिए पूरे आर्ग सूची के आसपास कोष्ठक जोड़ें:

sub cmpfunc { 
    return(($a->[0] <=> $b->[0]) or 
      ($a->[1] <=> $b->[1]) or 
      ($a->[2] <=> $b->[2])); 
} 
+8

* या * कड़ा बाध्यकारी या: '||' का उपयोग करें। – Axeman

5

अधिक कोष्ठकों की जरूरत:

sub cmpfunc { 
    return (($a->[0] <=> $b->[0]) or 
      ($a->[1] <=> $b->[1]) or 
      ($a->[2] <=> $b->[2])); 
} 
9

कारण आप इस "गलत" व्यवहार का निरीक्षण or ऑपरेटर, सबसे कम प्राथमिकता है मुमकिन। इस स्थिति में यह मतलब है कि

return ($a->[0] <=> $b->[0]) or 
     ($a->[1] <=> $b->[1]) or 
     ($a->[2] <=> $b->[2]); 

के रूप में व्याख्या की है या-इंग

return ($a->[0] <=> $b->[0]) 

और लाइन के बाकी -, इस मामले में बकवास वापसी के रूप में देता है कभी नहीं। यहाँ

return ($a->[0] <=> $b->[0]) || 
     ($a->[1] <=> $b->[1]) || 
     ($a->[2] <=> $b->[2]); 
+1

धन्यवाद, || एक अच्छा विकल्प है। – jftsai

3
sub cmpfunc { 
    return ($a->[0] <=> $b->[0]) or 
      ($a->[1] <=> $b->[1]) or 
      ($a->[2] <=> $b->[2]); 
} 

आप 'वापसी' हटा सकते हैं: :)

तो तुम सी या उपयोग करना चाहिए।

sub cmpfunc { 
    ($a->[0] <=> $b->[0]) or 
    ($a->[1] <=> $b->[1]) or 
    ($a->[2] <=> $b->[2]); 
} 
+0

यह अभी भी पहला कथन वापस करेगा जो सत्य का मूल्यांकन करता है। –

+1

@ लियोनार्डोहेरेरा ऐसा करना है। – TLP

+0

@ टीएलपी - दोह, आप सही हैं। –

2

डैनियल के लिए एक वैकल्पिक समाधान:

sub cmpfunc { 
    return ($a->[0] <=> $b->[0]) || 
      ($a->[1] <=> $b->[1]) || 
      ($a->[2] <=> $b->[2]); 
} 

or इस मामले के साथ समस्या यह काम की तुलना में कम पूर्वता है, इसलिए अपने कार्य केवल ($a->[0] <=> $b->[0]) का परिणाम है, जो -1 है देता है, 0 या 1 यदि बाएं हाथ की तरफ क्रमशः दाएं हाथ की तुलना में बराबर या उससे अधिक संख्यात्मक रूप से कम है।|| की उच्च प्राथमिकता है, इसलिए पूरे बूलियन अभिव्यक्ति का मूल्यांकन करने से पहले मूल्यांकन किया जाता है। जैसा कि बताया गया है, यदि आप || पर पसंद करते हैं तो आप अभिव्यक्ति को कोष्ठक में लपेट सकते हैं। मैं व्यक्तिगत रूप से नहीं करता हूं।

+0

वास्तव में, यह केवल पहले की तुलना, रिटर्न कोई फर्क नहीं पड़ता कि यह क्या देता है। 'Sub a {return 0 या die" Ough "}' का प्रयास करें। – TLP

+0

@TLP: उनका कहना है कि बाहर के लिए धन्यवाद। – flesk

संबंधित मुद्दे