2010-05-14 24 views
9

के लिए intersect मैं ऑब्जेक्ट सरणी के लिए array_intersect को जानना चाहता हूं।सरणी ऑब्जेक्ट सरणी php

+0

"ऑब्जेक्ट सरणी" से आपका क्या मतलब है - क्या आपका मतलब वस्तुओं की एक सरणी है? – thetaiko

+0

हाँ, यह वस्तुओं की सरणी है। –

उत्तर

2

array_intersect() सभी तर्कों में मौजूद array1 के सभी मानों वाला एक सरणी देता है।

Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same.

तो फिर तुम की सरणी पर इसका इस्तेमाल नहीं कर सकते हैं:

तो क्या इस संदर्भ (exacly इस समारोह) में मौजूद मतलब है, मैं अपने जवाब पर php.net पाया ऑब्जेक्ट्स यदि आपकी ऑब्जेक्ट स्ट्रिंग में अद्वितीय रूपांतरण लागू नहीं करती हैं।

+4

यह निर्विवाद है। कम से कम तीन तरीकों को एक स्ट्रिंग में परिवर्तित किया जा सकता है। वे एक PHP वर्ग हो सकते हैं और __toString को कार्यान्वित कर सकते हैं, उनके पास एक कास्ट हैंडलर हो सकता है जो IS_STRING स्वीकार करता है और उनके पास एक हैंडलर हो सकता है जो एक स्ट्रिंग में परिवर्तनीय है जो एक zval देता है। – Artefacto

+0

+1 @Atetefacto, मनमानी वस्तुओं और array_intersect() का उपयोग कर एक उदाहरण के साथ एक उत्तर सबमिट करें। – Dolph

+0

यदि आपकी ऑब्जेक्ट स्ट्रिंग में अद्वितीय रूपांतरण लागू नहीं करती हैं। – Svisstack

1

यह जांचने का सही तरीका है कि दो ऑब्जेक्ट बराबर हैं == का उपयोग करना है। इसलिए:

array_uintersect($arr1, $arr2, function ($a1, $a2) { return $a1 == $a2; }); 
+0

यह काम नहीं करता है .. आपके पास कोई अन्य कोडिंग है? –

+1

आपको और अधिक विशिष्ट होना होगा। क्या काम नहीं करता है? क्या कोई त्रुटि संदेश है? क्या त्रुटि संदेश? आउटपुट अपेक्षित नहीं है? क्या उम्मीद थी? तुम्हें क्या मिला? – Artefacto

+1

यह काम नहीं करता है क्योंकि array_unintersect को तुलनात्मक फ़ंक्शन की आवश्यकता 1, -1, या 0 पूर्ण स्पष्टीकरण और उदाहरण http://php.net/manual/en/function.array-uintersect के लिए यहां देखें। PHP # 72841 – Tim

6

अच्छा toString समारोह को पहले से ही लागू किया गया है और serialize कहा जाता है;) तो

array_map(
    'unserialize', 
    array_intersect(
     array_map(
      'serialize', 
      $obj1 
     ), 
     array_map(
      'serialize', 
      $obj2 
     ) 
    ) 
); 

काम करेंगे, उदाहरण के उच्च उल्लेख किया 'काम नहीं करते array_intersect काम के केवल किसी के रूप में तार के साथ का कारण उल्लेख किया गया है

+0

उत्कृष्ट हैक। पूरी तरह से काम करता है :) – yitwail

+0

आगे विचार पर, ऑब्जेक्ट्स के तरीके होने पर यह पर्याप्त नहीं है। जब आप क्रमबद्ध करते हैं, तो आप methpds खो देते हैं, इसलिए केवल गुणों को संरक्षित किया जाता है – yitwail

2

कुछ दिनों पहले इसी तरह की समस्या थी, जबकि ये जवाब सही रास्ते पर हैं; मैं उन्हें निम्नलिखित बाहर काम करने के लिए प्रयोग किया जाता:

Artefacto के जवाब return $obj1 == $obj2 वास्तव में काम नहीं किया है, तो मैं एक साधारण तुलनात्मक समारोह लिखा था (मूल रूप से धारावाहिक वस्तु की md5 हो जाता है और है कि तुलना):

function object_compare($obj1, $obj2){ 
    $md5 = function($obj){ 
    return md5(serialize($obj)); 
    }; 
    return strcmp($md5($obj1), $md5($obj2)); 
} 

तो यह चौराहे पाने के लिए हमारे तुलनात्मक समारोह के साथ array_uintersect बुला की बात बहर है:

# $array1/$array2 are the array of objects we want to compare 
return array_uintersect($array1, $array2, 'object_compare'); 

मेरे मामले में, मैं वस्तुओं की एक अज्ञात/गतिशील सरणी थी, इसलिए मैं इसे एक कदम आगे ले लिया तो मैं डॉन 'घोषित नहीं करना हैविशेष रूप से - लेकिन सिर्फ (वस्तुओं की) सरणियों की एक सरणी में पारित करने के लिए सक्षम हो:

# $multiarray_of_objects is our array of arrays 
$multiarray_of_objects[] = 'object_compare'; 
return call_user_func_array('array_uintersect', $multiarray_of_objects); 

बस होगा हमारे कॉलबैक के संदर्भ सरणी में अंतिम स्ट्रिंग के रूप/तुलनात्मक समारोह में पारित करने के लिए याद है। एक जादू की तरह काम करता है!

+0

नियंत्रक वर्ग के अंदर काम करने के कारण, मैं इसे ऐसा नहीं कर सका, लेकिन आर्टेफैक्टो के प्रारूप के साथ आपके दृष्टिकोण का उपयोग करके आकर्षण की तरह काम किया। – Magnanimity

+0

कक्षा में 'वापसी array_uintersect ($ array1, $ array2,' self :: object_compare ');' काम करना चाहिए, या यहां तक ​​कि 'ClassName :: object_compare' भी, लेकिन याद रखें कि इसे सार्वजनिक कक्षा फ़ंक्शन होने की आवश्यकता है। – Atari

0

मैं array_udiff का उपयोग object array के लिए array_intersect को लागू करने के लिए करता हूं।

function diff($a, $b) { 
if($a === $b) { 
    return 0; 
} else { 
    return 1;} 
} 

$array_1 = array('a', 'b', 'c');  

$array_2 = array('c', 'd','e');  

$array = array_udiff($array_1, array_udiff($array_1, $array_2, 'diff'),'diff'); 

var_dump($array); 
return array(1) { [2]=> string(1) "c" } 

आप किसी भी योजना के लिए अपना स्वयं का अंतर कार्य कर सकते हैं।

8

आप spl_object_hash साथ संयोजन के रूप में उपयोग कर सकते हैं array_uintersect, एक उदाहरण देखें:

array_uintersect($a, $b, function($a, $b) { 
     return strcmp(spl_object_hash($a), spl_object_hash($b)); 
    }); 

जहां '$ एक' और '$ ख' कुछ वस्तुओं है कि आप एक दूसरे को काटना चाहता हूँ की सरणियों कर रहे हैं।

+0

अच्छा समाधान। समकालीन पाठकों के लिए: php7 में, 'strcmp() 'को' <=> 'ऑपरेटर के साथ प्रतिस्थापित किया जा सकता है, जैसे:' return spl_object_hash ($ a) <=> spl_object_hash ($ b); ' –

-1

सही समाधान होगा:

array_uintersect($arr1, $arr2, function ($a1, $a2) { return $a1 != $a2; }); 

नोट = कॉलबैक समारोह के रूप में @Artefacto से जवाब के लिए विरोध में!। array_uintersect के प्रलेखन के आधार पर, यदि सरणी आइटम बराबर हैं तो कॉलबैक फ़ंक्शन को 0 (झूठा) वापस करना होगा।

+0

यह एक अनावश्यक प्रकार हैक है, कॉलबैक फ़ंक्शन को पूर्णांक (-1, 0, 1) वापस करना चाहिए यदि पहला मान दूसरे से बराबर या उससे अधिक है, जैसे फ़ंक्शंस सॉर्ट करना। झूठ से 0 का अंतर्निहित टाइपकास्ट आपके कोड के पाठकों को भ्रमित करेगा। – amik

0

बस पूर्णता के लिए: एक अद्वितीय मूल्य लौटने पर आपकी ऑब्जेक्ट में __toString() विधि लागू करें। डेटाबेस इकाइयों के लिए यह रिकॉर्ड की आईडी के साथ पोस्ट किए गए पूरी तरह से योग्य क्लास नाम को वापस करने के रूप में आसान हो सकता है। लेकिन यह कुछ हैशिंग या इससे भी बदतर चीजों को करके मनमाने ढंग से जटिल भी हो सकता है।

मेरी राय में, यह कक्षा का कर्तव्य है कि वह स्वयं को क्रमबद्ध करें या अपनी वस्तुओं की तुलना करने के लिए कुछ अद्वितीय बनाएं। किसी ऑब्जेक्ट को क्रमबद्ध करने के लिए कक्षा के बाहर किसी भी चीज का उपयोग करने से अजीब व्यवहार हो सकता है (विभिन्न वर्गों की वस्तुओं की तुलना सहित, जो समानता में कभी भी परिणाम नहीं लेना चाहिए)।