2009-07-07 14 views
11

यह वास्तव में एक गूढ़ सवाल है, लेकिन मैं वास्तव में उत्सुक हूं। मैं आजकल पहली बार यूसुर्ट का उपयोग कर रहा हूं, और मुझे विशेष रूप से दिलचस्पी है कि वास्तव में क्या चल रहा है।PHP का यूएसओटी कॉलबैक फ़ंक्शन पैरामीटर्स

$myArray = array(1, 9, 18, 12, 56); 

मैं usort के साथ इस सॉर्ट सकता है::

usort($myArray, function($a, $b){ 
    if ($a == $b) return 0; 
    return ($a < $b) ? -1 : 1; 
}); 

मैं क्या दो पैरामीटर $ एक और $ के साथ चल रहा है के बारे में 100% स्पष्ट नहीं कर रहा हूँ मैं निम्नलिखित सरणी मिल गया है मान लीजिए ख। वे क्या हैं, और वे क्या प्रतिनिधित्व करते हैं। मेरा मतलब है, मैं मान सकता हूं कि $ एक सरणी में वर्तमान आइटम का प्रतिनिधित्व करता है, लेकिन इसकी तुलना वास्तव में क्या हो रही है? $ बी क्या है?

मैं तार शामिल करने के लिए मेरी सरणी बढ़ सकते हैं:

$myArray = array(
    array("Apples", 10), 
    array("Oranges", 12), 
    array("Strawberries", 3) 
); 

और निम्नलिखित चलाएँ:

usort($myArray, function($a, $b){ 
    return strcmp($a[0], $b[0]); 
}); 

और वह मेरे बच्चे-सरणियों वर्णानुक्रम [0] सूचकांक मूल्य पर आधारित सॉर्ट होगा। लेकिन यह $ और $ बी के बारे में कोई स्पष्टता प्रदान नहीं करता है। मुझे केवल इतना पता है कि मैं जिस पैटर्न की तलाश कर रहा हूं उससे मेल खाता हूं।

क्या कोई वास्तव में क्या हो रहा है इसके बारे में कुछ स्पष्टता प्रदान कर सकता है?

+0

+1 मैंने हमेशा ऐसा ही सोचा है। – alex

उत्तर

5

किसी भी चीज को सॉर्ट करने के लिए आपको दो वस्तुओं की तुलना करने के लिए एक साधन की आवश्यकता है और पता लगाएं कि कोई दूसरे के सामने आता है या नहीं। यह वही है जो आप usort को आपूर्ति करते हैं। यह समारोह अपने इनपुट सरणी से दो आइटम पारित हो जाएगा, और क्रम में वे

में। एक बार जब आप दो तत्वों की तुलना करने के लिए एक साधन है, तो आप तरह-एल्गोरिथ्म के- अपने पसंद का उपयोग कर सकते हैं होना चाहिए देता है।

यदि आप अपरिचित हैं, तो आप यह देखना चाहेंगे कि bubblesort जैसे सरल बेवकूफ एल्गोरिदम तुलनात्मक फ़ंक्शन का उपयोग कैसे करेंगे।

दृश्यों के पीछे, PHP quicksort का उपयोग कर रहा है।

+2

मेरा मानना ​​है कि जोनाथन "दृश्यों के पीछे" भाग में रूचि रखता है। –

31

$ ए और $ बी की सटीक परिभाषा सरणी को सॉर्ट करने के लिए उपयोग किए गए एल्गोरिदम पर निर्भर करेगी। किसी भी चीज को सॉर्ट करने के लिए आपके पास दो तत्वों की तुलना करने का साधन होना चाहिए, यही कॉलबैक फ़ंक्शन के लिए उपयोग किया जाता है। कुछ सॉर्टिंग एल्गोरिदम सरणी में कहीं भी शुरू कर सकते हैं, अन्य केवल इसके विशिष्ट हिस्से में ही शुरू हो सकते हैं, इसलिए कोई का अर्थ $ ए और $ बी में नहीं है, इसके अलावा वे सरणी में दो तत्व हैं जिनकी तुलना तुलना की जानी चाहिए वर्तमान एल्गोरिदम।

इस विधि का उपयोग प्रकाश को शेड करने के लिए किया जा सकता है जिस पर एल्गोरिदम PHP का उपयोग कर रहा है।

<?php 

$myArray = array(1, 19, 18, 12, 56); 

function compare($a, $b) { 
    echo "Comparing $a to $b\n"; 
    if ($a == $b) return 0; 
    return ($a < $b) ? -1 : 1; 
} 

usort($myArray,"compare"); 
print_r($myArray); 
?> 

आउटपुट

[email protected]:~$ php sort.php 
Comparing 18 to 19 
Comparing 56 to 18 
Comparing 12 to 18 
Comparing 1 to 18 
Comparing 12 to 1 
Comparing 56 to 19 
Array 
(
    [0] => 1 
    [1] => 12 
    [2] => 18 
    [3] => 19 
    [4] => 56 
) 
उत्पादन से

और स्रोत हम देख सकते हैं इस्तेमाल किया प्रकार वास्तव में एक quicksort कार्यान्वयन है, पीएचपी स्रोत (संस्करण से जुड़ा हुआ में Zend/zend_qsort.c के लिए जाँच को देखकर थोड़ा है पुराना है, लेकिन ज्यादा नहीं बदला है)।

यह इस मामले में 18 के सरणी में पिवट को चुनता है, तो उसे सूची को फिर से व्यवस्थित करने की आवश्यकता होती है ताकि पिंड के मुकाबले सभी तत्व जो कम हो (तुलना में तुलनात्मक कार्य के अनुसार) और इसलिए कि पिवट से अधिक सभी तत्व इसके बाद आते हैं, हम इसे ऐसा कर सकते हैं जब यह सब कुछ पहले 18 पर तुलना करता है।

कुछ और आरेखण स्पष्टीकरण।

 
Step 0: (1,19,18,12,56); //Pivot: 18, 
Step 1: (1,12,18,19,56); //After the first reordering 
Step 2a: (1,12);   //Recursively do the same with the lesser, here 
         //pivot's 12, and that's what it compares next if 
         //you check the output. 
Step 2b: (19,56);  //and do the same with the greater 
+0

उत्कृष्ट जवाब। पॉल पर्याप्त था, और पहले। इसलिए मैंने उन्हें स्वीकृति दी। हालांकि मैंने तुम्हारा उत्साह बढ़ाया है और आपकी पूर्णता की सराहना की है। – Sampson

+7

तर्क के लिए, मैं सुझाव दूंगा कि पहले हमेशा बेहतर नहीं होता है। यदि दूसरा उत्तर अधिक पूर्ण है तो लोगों को पूरी तरह से प्रश्न का उत्तर देने के लिए समय निकालने के लिए पुरस्कृत किया जाना चाहिए। – acrosman

0

usort() या uasort() क्रमबद्ध परिणाम पर एक मानव भावना बग है।

function xxx($a,$b) { if ($a==$b) return 0; else return $a<$b?-1:1; } 
$x=array(1=>10,2=>9,3=>9,4=>9,5=>6,6=>38); 
uasort($x,'xxx'); 
print_r($x); 

परिणाम है::

Array ([5] => 6 [4] => 9 [3] => 9 [2] => 9 [1] => 10 [6] => 38) 

आप बग दिखाई दे रही है कोड खंड देखते हैं? नहीं? ठीक है, मुझे इसे समझाओ। मूल तीन '9' elments मुख्य क्रम में हैं: 2,3,4। लेकिन नतीजतन, तीन '9' तत्व अब मुख्य क्रम में हैं: 4,3,2, यानी बराबर-मूल्य तत्व सॉर्ट करने के बाद रिवर्स कुंजी ऑर्डर में हैं।

यदि तत्व केवल एक मान है, जैसा उपर्युक्त उदाहरण में है, तो यह हमारे साथ ठीक है। हालांकि, यदि तत्व यौगिक मूल्य है, तो यह मानव-महसूस करने वाली बग का कारण बन सकता है। एक और कोड सेगमेंट देखें।

function xxx($a,$b) { if ($a['x']==$b['x']) return 0; else return $a['x']<$b['x']?-1:1; } 
$x=array(1=>array('x'=>1, 'v'=>'l'),2=>array('x'=>9, 'v'=>'love'), 
     3=>array('x'=>9, 'v'=>'Lara'),4=>array('x'=>9, 'v'=>'Croft'), 
     5=>array('x'=>15, 'v'=>'and'),6=>array('x'=>38, 'v'=>'Tombraider')); 
uasort($x,'xxx'); 
print_r($x); 

परिणाम है::

Array ([1] => Array ([x] => 1 [v] => l) [4] => Array ([x] => 9 [v] => croft) 
      [3] => Array ([x] => 9 [v] => Lara) [2] => Array ([x] => 9 [v] => love) 
      [5] => Array ([x] => 15 [v] => and) [6] => Array ([x] => 38 [v] => Tombraider)) 

तुम देखो 'मैं लारा क्रॉफ्ट और Tombraider प्यार हम निर्देशांक एक्स मूल्य क्षैतिज रूप कई बिंदुओं सॉर्ट करने के लिए, यानी प्रकार इन्हें आरोही के आधार पर कर रहे हैं 'बन जाता है' आई क्रॉफ्ट लारा प्यार और टॉम्बराइडर '।

मैं इसे मानव भावना बग क्योंकि यह क्या मामला आप उपयोग पर निर्भर करता है और आप कैसे लगता है कि यह असली दुनिया में सॉर्ट किया जाना चाहिए जब तुलना में मूल्यों ही कर रहे हैं कहते हैं।

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