2012-02-27 14 views
5

साफ़ नहीं है सबसे पहले मुझे यह उल्लेख करने की आवश्यकता है कि मैंने मैन्युअल और PHP दस्तावेज़ों में खोला और जवाब नहीं मिला। यहाँ है एक कोड मैं का उपयोग करें:array_diff_uassoc का व्यवहार

class chomik { 

    public $state = 'normal'; 
    public $name = 'no name'; 

    public function __construct($name) { 
     $this->name = $name; 
    } 

    public function __toString() { 
     return $this->name . " - " . $this->state; 
    } 
} 

function compare($a, $b) { 
    echo("$a : $b<br/>"); 
    if($a != $b) { 
     return 0; 
    } 
    else return 1; 
} 

$chomik = new chomik('a'); 
$a = array(5, $chomik, $chomik, $chomik); 
$b = array($chomik, 'b', 'c', 'd'); 
array_diff_uassoc($a, $b, 'compare'); 

मैं क्या सोचा, array_diff_uassoc इन दो सरणियों के सभी मूल्यों की तुलना करेंगे, और अगर मान मौजूद है, तो कुंजी तुलना चलेंगे। और इस कोड का आउटपुट है:

1 : 0 
3 : 1 
2 : 1 
3 : 2 
1 : 0 
3 : 1 
2 : 1 
3 : 2 
3 : 3 
3 : 2 
2 : 3 
1 : 3 
0 : 3 

तो सबसे पहले कुछ जोड़े (1: 0 या 3: 1) डुप्लीकेट क्यों हैं? क्या इसका मतलब यह है कि फ़ंक्शन भूल गया है कि यह पहले से ही इस आइटम की तुलना करता है? मैंने सोचा कि यह सभी बराबर मूल्य वाले जोड़ों की तुलना करेगा, लेकिन मैं इसे आउटपुट में नहीं देखता हूं। क्या मैं कुछ भूल रहा हूँ?

तो प्रश्न यह है कि तुलना के क्रम में इस कार्य का सटीक व्यवहार क्या है, और मैं यह डुप्लीकेट क्यों देखता हूं? (मेरे PHP संस्करण है, अगर यह मदद करता है: PHP संस्करण 5.3.6-13ubuntu3.6)

मैं वास्तव में उलझन में हूँ, और इसके बारे में कुछ अच्छा स्पष्टीकरण के लिए इंतज़ार कर ...

+1

आपको शायद सख्त तुलना का उपयोग करना चाहिए!तुलनात्मक कार्य में == नहीं ==। –

+0

तुलना इस मामले में ईमानदार होने का एक बड़ा सौदा नहीं है। मैं सोच रहा हूं कि तुलना करते समय 'echo' ऐसे परिणामों को क्यों प्रिंट कर रहा है। और 'echo' तुलना से पहले ट्रिगर किया गया है, इससे कोई फर्क नहीं पड़ता कि यह सख्त है या नहीं। – Karol

+0

जो मैं इस कोड को लिखना चाहता था वह है: मैं केवल इन तत्वों को चाहता हूं जो दूसरे सरणी में नहीं हैं ($ a [0]), और यदि वे दूसरे सरणी में हैं, तो मैं इन तत्वों को चाहता हूं जिनके पास एक ही कुंजी है (अनुक्रमणिका) ... तो निश्चित रूप से फ़ंक्शन को केवल $ [0] – Karol

उत्तर

0

op'scomment कि

से

मैं केवल इन तत्वों जो दूसरी सरणी में नहीं हैं चाहते हैं ($ एक [0])

आप array_diff($a, $b); उपयोग नहीं कर सकते? यह

array(1) { 
    [0]=> 
    int(5) 
} 

अन्यथा,

The documentation कहा गया है कि रिटर्न:

तुलना समारोह एक पूर्णांक से कम लौटना चाहिए, के बराबर, या शून्य से अधिक है, तो पहला तर्क है माना जाता है, क्रमशः से कम, बराबर या उससे अधिक।

मैं यह समझ के रूप में, इसका मतलब है कि कि compare() समारोह इस तरह अधिक होना चाहिए:

function compare($a, $b) { 
    echo("$a : $b<br/>"); 
    if($a === $b) return 0; 
    else if ($a > $b) return 1; 
    else return -1; 
} 

हालांकि यहां तक ​​कि इन संशोधनों के साथ, यह बहुत ही अजीब तुलना गया है परिणाम:

 
1 : 0 
1 : 2 
3 : 1 
2 : 1 
3 : 2 
1 : 0 
1 : 2 
3 : 1 
2 : 1 
3 : 2 
0 : 0 
1 : 0 
1 : 1 
2 : 0 
2 : 1 
2 : 2 
3 : 0 
3 : 1 
3 : 2 
3 : 3 

मैंने इस बारे में another question से पूछा क्योंकि यह किसी उत्तर के दायरे से बाहर हो रहा था।

0

मुझे लगता है कि आप रिटर्न वैल्यू सेक्शन चूक गए हैं।

सरणी 1 से सभी प्रविष्टियों वाली एक सरणी देता है जो किसी भी अन्य सरणी में मौजूद नहीं है।

तुलना में सरणी कुंजियों का उपयोग किया जाता है।

पाठ में क्या गुम है यह है कि तुलना केवल सहयोगी ही की जाती है।इसका मतलब है कि स्वचालित रूप से घोषित या उपयोगकर्ता परिभाषित संख्यात्मक कुंजी स्ट्रिंग्स पूर्णांक के रूप में टाइप की जाती हैं।

तो साथ

$one = array(a,b,c,'hot'=>d); // d has no match and will be returned as array and go to the function alone 
$two = array(a,b,c,d,e,f); // 

क्योंकि $ एक हॉट => घ $ दो 0 => घ एक साहचर्य स्तर पर $ से मेल नहीं खाता गर्म => घ दिया जाता है।

स्ट्रिंग और पूर्णांक डेटा प्रकार की PHP क्विर्क की वजह से उपयोगकर्ता परिभाषित फ़ंक्शन तुलनात्मक रूप से मजबूत तुलना संचालन जैसे === का उपयोग करके तुलना को बढ़ाने के लिए उपयोग किया जा सकता है।

यह परिस्थितियों में मदद करता है जहां प्रकार संदिग्ध '0' => डी और 0 => डी समान दिख सकता है लेकिन जब तक आप अपने कोड में ऐसा नहीं कहेंगे।

सौभाग्य से संकेत इस प्रकार के अजीब निर्माण और अस्पष्ट दस्तावेज से छुटकारा पाने के लिए PHP7 पर आ रहा है।

मैं इसे अपनी टिप्पणी से जोड़ रहा हूं क्योंकि यह आपकी समझ से संबंधित है कि आपके मामले में कौन सी php संरचनाओं का सबसे अच्छा उपयोग किया जाता है। मेरी टिप्पणी:

मुझे इस बारे में इतना यकीन नहीं है कि अगर ($ a! = $ B) {उनके कोड में समस्या है। चूंकि वे गलती से समानता का उपयोग कर रहे हैं, जब वे समान ऑपरेटर का उपयोग कर होना चाहिए! ==। और वे संरचनात्मक कुंजी के लिए डिज़ाइन किए गए निर्माण में संख्यात्मक कुंजी का उपयोग कर रहे हैं। वे शायद array_udiff से अनजान हैं जो

+0

यह बहुत स्पष्ट है कि आप यहां क्या कह रहे हैं इसके बारे में बहुत जागरूक हैं। –

+1

मुझे इस बारे में इतना यकीन नहीं है कि अगर ($ a! = $ B) {उनके कोड में एक समस्या है। चूंकि वे गलती से समानता का उपयोग कर रहे हैं जब उन्हें समान ऑपरेटरों का उपयोग करना चाहिए। और वे सहयोगी कुंजी के लिए डिज़ाइन किए गए निर्माण में संख्यात्मक कुंजी का उपयोग कर रहे हैं। वे शायद array_udiff से भी अनजान हैं जो –

0

यह कुछ हद तक दिलचस्प है। मैंने जीथ्यूब पर PHP का नवीनतम स्रोत देखा (जिसे सी ++ में लिखा गया है जैसा कि आप शायद जानते हैं) और इसे समझने की कोशिश की। (https://github.com/php/php-src/blob/master/ext/standard/array.c)

एक त्वरित खोज मुझे पता चला है कि प्रश्न में समारोह 4308

PHP_FUNCTION(array_diff_uassoc) 
{ 
    php_array_diff(INTERNAL_FUNCTION_PARAM_PASSTHRU, DIFF_ASSOC, DIFF_COMP_DATA_INTERNAL, DIFF_COMP_KEY_USER); 
} 

ताकि पता चलता है कि वास्तविक काम php_array_diff समारोह द्वारा किया जाता है, कि एक ही में पाया जा सकता लाइन पर घोषित किया जाता है लाइन 3 9 38 पर फ़ाइल करें। इसे यहां पेस्ट करने के लिए थोड़ा लंबा है, 265 लाइनें सटीक हैं, लेकिन यदि आप चाहें तो इसे देख सकते हैं।

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

सब

कहने के लिए सिर्फ एक लंबे परिचय है, कारण है कि आप पहली जगह में अपने compare समारोह के अंदर एक echo रखना चाहते हैं? array_diff_uassoc का लक्ष्य फ़ंक्शन का आउटपुट है। आपको इस पर भरोसा नहीं करना चाहिए कि पार्सर इसे कैसे संभालता है। अगर वे कल उस समारोह के आंतरिक कार्यों को यानी बदलने के लिए तय करते हैं। पहले मूल्य तुलना करें, आपको एक पूरी तरह से अलग परिणाम मिल जाएगा।

शायद आप इस प्रतिस्थापन समारोह है कि php में लिखा है इस्तेमाल कर सकते हैं: http://pear.php.net/reference/PHP_Compat-1.6.0a2/__filesource/fsource_PHP_Compat__PHP_Compat-1.6.0a2CompatFunctionarray_diff_uassoc.php.html

इस तरह आप व्यवहार पर भरोसा कर सकते नहीं बदलने के लिए, और आप आंतरिक कार्यप्रणाली का पूरा नियंत्रण है ...

+0

में शामिल डेटा के लिए एक बेहतर मिलान है, यह आपके जीथब लिंक की लाइन 3631 है: '} और यदि (व्यवहार और INTERSECT_ASSOC && key_compare_type == INTERSECT_COMP_KEY_USER) {'। लाइन 3321 एक खाली रेखा है। यह स्पष्ट है कि इको कार्यक्षमता के लिए नहीं बल्कि परीक्षण के लिए बनाया गया है, और यह अजीब परिणाम दिखाता है। –

+1

@ फ़ेलिक्सगैगन-ग्रेनेयर क्षमा करें, मैंने वहां लाइन नंबरों को गड़बड़ कर दिया है (मैंने वास्तव में php.net से स्रोत डाउनलोड किया है और बाद में पता चला कि स्रोत गीथूब पर भी था। सोचा था कि वहां लिंक करना आसान होगा लेकिन जांचना भूल गया लाइन नंबर। Ctrl/Cmd + F आपको वहां लाएगा) अभी अपडेट किया गया है, लेकिन चूंकि लिंक वर्तमान मास्टर को इंगित करता है, इसलिए भविष्य में यह फिर से बदल सकता है। – Pevara

+1

मेरे उत्तर का मुद्दा यह है कि आपको उस काले रंग के बॉक्स पर विचार करना चाहिए और इसके आंतरिक कार्यों पर भरोसा नहीं करना चाहिए। यह एपीआई और आउटपुट के बारे में है, अब * समारोह * उस परिणाम को कैसे प्राप्त होता है, क्योंकि भविष्य में यह बदल सकता है। – Pevara

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