दो php Doctrine 2 ArrayCollection () को कैसे मर्ज करें


82

क्या कोई सुविधा विधि है जो मुझे दो सिद्धांत को समाप्‍त करने की अनुमति देती है ArrayCollection()? कुछ इस तरह:

$collection1 = new ArrayCollection();
$collection2 = new ArrayCollection();

$collection1->add($obj1);
$collection1->add($obj2);
$collection1->add($obj3);

$collection2->add($obj4);
$collection2->add($obj5);
$collection2->add($obj6);

$collection1->concat($collection2);

// $collection1 now contains {$obj1, $obj2, $obj3, $obj4, $obj5, $obj6 }

मैं सिर्फ यह जानना चाहता हूं कि क्या मैं 2 संग्रह से अधिक पुनरावृत्ति होने से बचा सकता हूं और प्रत्येक तत्व को 1 से 1 संग्रह में जोड़ सकता हूं।

धन्यवाद!


3
+1 क्योंकि इसकी एक सामान्य और आवश्यक विधि
JavierIEH

जवाबों:


171

मेरे लिए बेहतर (और काम करने वाला) प्रकार:

$collection3 = new ArrayCollection(
    array_merge($collection1->toArray(), $collection2->toArray())
);

सर्वश्रेष्ठ उत्तर, कोई संदेह नहीं।
Carles

मैं इस समाधान की सलाह देता हूं
ioleo

मैं ऐसा ही करने की कोशिश कर रहा हूं, लेकिन एक सरणी में: array_merge ($ merged_arr, $ doct_collection-> toArray ()); लेकिन मुझे या तो कोई त्रुटि नहीं मिल रही है या यह काम कर रहा है ($ merged_arr खाली है)। कोई विचार?
गाइ

5
हो सकता है कि $ मर्ज_र = अरेंज_मरेज ($ मर्ज_र, $ doct_collection-> toArray ()) हो?
प्लिश्कौ

12

आप बस कर सकते हैं:

$a = new ArrayCollection();
$b = new ArrayCollection();
...
$c = new ArrayCollection(array_merge((array) $a, (array) $b));

6
मुझे समझ में नहीं आता कि यह इतने सारे अपवित्र क्यों हो जाते हैं। यह केवल गलत है। किसी ऑब्जेक्ट को किसी सरणी में कास्टिंग करना कॉल नहीं करता है toArray()देखें क्या होता है
greg0ire

21
जब भी भीड़ की मानसिकता हमेशा मज़ेदार होती है, तो क्या आप में से किसी ने इसे नकारने से पहले वास्तव में कोशिश की थी? ArrayCollection IteratorAggregate को कार्यान्वित करता है जो आपको संग्रह को एक सरणी के रूप में प्रस्तुत करने की अनुमति देता है और यह अपेक्षित रूप से काम करेगा।
लुईस

5
भगवान का शुक्र है, कोई स्मार्ट!
डेनियल रिबेरो

1
@ लेविस: इसने इससे पहले यह किया था, यह मेरे लिए काम नहीं करता था (मुझे इसमें आने का कोई समय नहीं था)। यही कारण है कि मुझे
pliashkou

2
@Lewis: पार्टी में थोड़ी देर हो गई है, लेकिन मैं उस समस्या पर वापस आ रहा हूं, और हां मैंने इसकी कोशिश की, और नहीं, यह काम नहीं करता है, इसलिए पतन।
greg0ire

10

यदि आपको किसी डुप्लिकेट को रोकने की आवश्यकता है, तो यह स्निपेट मदद कर सकता है। यह PHP5.6 के साथ उपयोग के लिए एक वैरेडिक फ़ंक्शन पैरामीटर का उपयोग करता है।

/**
 * @param array... $arrayCollections
 * @return ArrayCollection
 */
public function merge(...$arrayCollections)
{
    $returnCollection = new ArrayCollection();

    /**
     * @var ArrayCollection $arrayCollection
     */
    foreach ($arrayCollections as $arrayCollection) {
        if ($returnCollection->count() === 0) {
            $returnCollection = $arrayCollection;
        } else {
            $arrayCollection->map(function ($element) use (&$returnCollection) {
                if (!$returnCollection->contains($element)) {
                    $returnCollection->add($element);
                }
            });
        }
    }

    return $returnCollection;
}

कुछ मामलों में काम हो सकता है।


1
या उपयोग करें$collection3 = new ArrayCollection(array_unique(array_merge($collection1->toArray(), $collection2->toArray())));
spdionis

हाँ, लेकिन यह और अन्य लोकप्रिय उत्तर जो एक ही काम करता है पूरे मॉडल ऑब्जेक्ट को सरणियों में परिवर्तित करता है, जो आगे की कार्यक्षमता को सीमित करता है।
शून्य और

3
$newCollection = new ArrayCollection((array)$collection1->toArray() + $collection2->toArray()); 

इससे तेज होना चाहिए array_merge$collection1उसी कुंजी नाम में मौजूद होने पर डुप्लिकेट कुंजी नामों को रखा जाता है $collection2। कोई फर्क नहीं पड़ता कि वास्तविक मूल्य क्या है


toArray()एक सरणी देता है, आपको arrayनिश्चित रूप से टाइप करने की आवश्यकता नहीं होनी चाहिए ?
जिम्बो

@ जिम्बो: आप सही हैं, लेकिन यदि किसी कारण से पहला $collection->toArray()रिटर्न nullया false। आप एक घातक त्रुटि के साथ समाप्त होते हैं।
कानारिज्वर्ट ३१'१६ को

उचित बिंदु - यद्यपि यदि डॉक्ट्रिन एक सरणी में परिवर्तित करने में विफल रहता है, तो डॉक्ट्रीन कोडबेयर के साथ कुछ गलत है;)
जिम्बो

2

एक सरणी की सामग्री को दूसरे में जोड़ने के लिए आपको अभी भी संग्रह पर पुनरावृति करने की आवश्यकता है। चूंकि ArrayCollection एक आवरण वर्ग है, इसलिए आप कुंजियों को बनाए रखते हुए तत्वों की सरणियों को मर्ज करने का प्रयास कर सकते हैं, $ collection2 में सरणी कुंजियाँ $ collection1 में किसी भी मौजूदा कुंजी को ओवरहाइड करके नीचे दिए गए सहायक फ़ंक्शन का उपयोग कर सकती हैं:

$combined = new ArrayCollection(array_merge_maintain_keys($collection1->toArray(), $collection2->toArray())); 

/**
 *  Merge the arrays passed to the function and keep the keys intact.
 *  If two keys overlap then it is the last added key that takes precedence.
 * 
 * @return Array the merged array
 */
function array_merge_maintain_keys() {
    $args = func_get_args();
    $result = array();
    foreach ( $args as &$array ) {
        foreach ( $array as $key => &$value ) {
            $result[$key] = $value;
        }
    }
    return $result;
}

के लिए &ऑपरेटर क्या है ? क्या यह C जैसा कुछ है? ठीक है, निश्चित रूप से यह एक समाधान है, लेकिन मुझे जो व्यवहार की उम्मीद थी, वह ArrayCollectionपहले से ही कुछ मूल्यों को समाहित करने के लिए थी, और ArrayCollectionकिसी अन्य मौजूदा के मूल्यों को जोड़ने के लिए एक विधि का उपयोग करें ( यदि यह मौजूद है, या आपकी तरह एक अलग प्रक्रिया)। ArrayCollection। आपके समाधान के लिए एक नया बनाने की आवश्यकता होती है ArrayCollection, जो प्रक्रिया को भारी बनाता है। फिर भी धन्यवाद!
थ्रॉज़

यह संदर्भ द्वारा एक पास है, क्योंकि आप तर्क बदलना नहीं चाहते हैं। आप इसके बजाय संग्रह पर पुनरावृति करने की विधि को फिर से लिख सकते हैं। इस पद्धति के लिए कोई तर्क नहीं हैं, इसलिए आप जितने चाहें उतने संग्रह जोड़ सकते हैं।
स्टीफन सेनकोमोगो मसोके

बात यह है कि, मुझे अपने स्रोत संग्रह गतिशील रूप से मिलते हैं, इसलिए मैं आपके द्वारा सुझाए गए तरीके से कॉल नहीं कर सकता ...
थ्रॉज़

मेरा आशय यह है कि आप एक विधि मर्ज-कलेक्शंस ($ collection1, $ collection2) लिख सकते हैं, जो $ collection2 की सामग्री को $ collection1 में मिला देता है। आप mergeCollection फ़ंक्शन का पुन: उपयोग कर सकते हैं, जहाँ आपके आवेदन के भीतर
Stephen Senkomago Musoke

इसके बजाय, आपको array_merge () का उपयोग करना चाहिए।
डैनियल रिबेरो

0

एक संग्रह में एक सरणी जोड़ें, जो यूरी प्लायाशको की टिप्पणी पर आधारित है (मुझे पता है कि यह सीधे मूल प्रश्न का उत्तर नहीं देता है, लेकिन यह पहले से ही उत्तर दिया गया था, और इससे दूसरों को यहां उतरने में मदद मिल सकती है):

function addCollectionToArray( $array , $collection ) {
    $temp = $collection->toArray();
    if ( count( $array ) > 0 ) {
        if ( count( $temp ) > 0 ) {
            $result = array_merge( $array , $temp );
        } else {
            $result = $array;
        }
    } else {
        if ( count( $temp ) > 0 ) {
            $result = $temp;
        } else {
            $result = array();
        }
    }
    return $result;
}

हो सकता है कि आप इसे पसंद करते हों ... शायद नहीं ... मैंने अभी इसे वहाँ फेंकने के बारे में सोचा था जब किसी को इसकी ज़रूरत हो।


संभव समाधानों में किसी प्रकार की विविधता के लिए हमेशा अच्छा होता है। लेकिन दूसरों की तुलना में, मुझे आपके समाधान का उपयोग करने में लाभ नहीं दिखता है। क्या आप इसे विस्तार से थोड़ा और बताएंगे?
k00ni

1
कुछ अन्य लोगों के रूप में एक सरणी में एक संग्रह जोड़ने की आवश्यकता होने पर मैं इस प्रश्न पर उतरा, लेकिन मेरे उपयोग-मामले को खाली सरणी / संग्रह के लिए जाँच की आवश्यकता थी, इसलिए मैंने इसे यहाँ साझा किया।
मानटैक्स

0

ध्यान! पुनरावर्ती तत्वों के बड़े घोंसले के शिकार से बचें। array_unique - एक पुनरावर्ती एम्बेडिंग सीमा है और इसका कारण बनता है aPHP error Fatal error: Nesting level too deep - recursive dependency?

/**
 * @param ArrayCollection[] $arrayCollections
 *
 * @return ArrayCollection
 */
function merge(...$arrayCollections) {
    $listCollections = [];
    foreach ($arrayCollections as $arrayCollection) {
        $listCollections = array_merge($listCollections, $arrayCollection->toArray());
    }

    return new ArrayCollection(array_unique($listCollections, SORT_REGULAR));
}

// using
$a = new ArrayCollection([1,2,3,4,5,6]);
$b = new ArrayCollection([7,8]);
$c = new ArrayCollection([9,10]);

$result = merge($a, $b, $c);

-1

Clousures PHP5> 5.3.0 का उपयोग करना

$a = ArrayCollection(array(1,2,3));
$b = ArrayCollection(array(4,5,6));

$b->forAll(function($key,$value) use ($a){ $a[]=$value;return true;});

echo $a.toArray();

array (size=6) 0 => int 1 1 => int 2 2 => int 3 3 => int 4 4 => int 5 5 => int 6

छोटा संकेत : भाग echo $a.toArray();निश्चित रूप से एक त्रुटि फेंक देगा, क्योंकि toArrayएक वैध फ़ंक्शन नहीं है। यह कम से कम होना चाहिए echo $a->toArray();। इसके अलावा, अंत में आउटपुट को कोड के रूप में स्वरूपित किया जाना चाहिए।
15:00 बजे k00ni
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.