Wie man zwei PHP Doctrine 2 ArrayCollection() zusammenführt

Lesezeit: 6 Minuten

Benutzer-Avatar
Schlucken

Gibt es eine praktische Methode, die es mir ermöglicht, zwei Lehren zu verketten? ArrayCollection()? etwas wie:

$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 }

Ich möchte nur wissen, ob ich es mir sparen kann, die 2. Sammlung zu durchlaufen und jedes Element einzeln zur 1. Sammlung hinzuzufügen.

Vielen Dank!

  • +1, weil es eine gängige und benötigte Methode ist

    – JavierIEH

    2. Oktober 2012 um 14:40 Uhr

Benutzer-Avatar
pliashkou

Bessere (und funktionierende) Variante für mich:

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

  • Ich versuche dasselbe zu tun, aber in ein Array: array_merge($merged_arr, $doct_collection->toArray()); bekomme aber weder einen Fehler noch funktioniert es ($merged_arr ist leer). Irgendwelche Ideen?

    – Kerl

    20. Oktober 2013 um 18:34 Uhr


  • Vielleicht $merged_arr = array_merge($merged_arr, $doct_collection->toArray()) ?

    – pliashkou

    21. Oktober 2013 um 9:49 Uhr

  • Beachten Sie den Unterschied zwischen numerischen und zugeordneten Arrays, wenn Sie diesen Weg gehen: Überschreiben vs. Anhängen.

    – Kaiser

    17. Januar um 10:00 Uhr

Benutzer-Avatar
Daniel Ribeiro

Sie können einfach Folgendes tun:

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

  • Ich verstehe nicht, warum das so viele Upvotes bekommt. Es ist einfach falsch. Das Umwandeln eines Objekts in ein Array ruft nicht auf toArray(). Schau was passiert

    – greg0ire

    13. Juni 2013 um 14:45 Uhr

  • Während Mob-Mentalität immer Spaß macht, hat jemand von euch das tatsächlich versucht, bevor er es abgelehnt hat? ArrayCollection implementiert IteratorAggregate, mit dem Sie die Sammlung in ein Array umwandeln können, und es funktioniert genau wie erwartet.

    – Lewis

    9. April 2014 um 13:47 Uhr

  • Gott sei Dank, jemand klug!

    – Daniel Ribeiro

    9. April 2014 um 13:55 Uhr

  • @Lewis: Es hat es vorher gerieben, es hat bei mir nicht funktioniert (ich hatte keine Zeit, mich darauf einzulassen). Deshalb musste ich eine andere Variante schreiben

    – pliashkou

    7. April 2015 um 14:29 Uhr


  • @Lewis: ein bisschen spät zur Party, aber ich komme auf dieses Problem zurück, und ja, ich habe es versucht, und nein, es funktioniert nicht, daher die Ablehnung.

    – greg0ire

    16. September 2015 um 16:40 Uhr

Wenn Sie Duplikate verhindern müssen, kann dieses Snippet hilfreich sein. Es verwendet einen variablen Funktionsparameter für die Verwendung mit 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;
}

Könnte in manchen Fällen praktisch sein.

  • Oder verwenden $collection3 = new ArrayCollection(array_unique(array_merge($collection1->toArray(), $collection2->toArray())));

    – spdionis

    31. Oktober 2018 um 20:53 Uhr


  • Ja, aber diese und die andere beliebte Antwort, die dasselbe tut, konvertiert das gesamte Modellobjekt in Arrays, was die weitere Funktionalität einschränkt.

    – Nullen und Einsen

    15. Juli 2020 um 18:52 Uhr

Benutzer-Avatar
kanariezwart

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

Das sollte schneller gehen als array_merge. Doppelte Schlüsselnamen von $collection1 werden beibehalten, wenn derselbe Schlüsselname in vorhanden ist $collection2. Egal wie hoch der tatsächliche Wert ist

Sie müssen immer noch über die Sammlungen iterieren, um den Inhalt eines Arrays einem anderen hinzuzufügen. Da die ArrayCollection eine Wrapper-Klasse ist, könnten Sie versuchen, die Arrays von Elementen zusammenzuführen, während Sie die Schlüssel beibehalten, die Array-Schlüssel in $collection2 überschreiben alle vorhandenen Schlüssel in $collection1 mit einer Hilfsfunktion unten:

$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;
}

  • Was ist das & Betreiber für? ist es so etwas wie in C? Nun, das ist natürlich eine Lösung, aber das Verhalten, das ich erwartet hatte, war eine ArrayCollection die bereits einige Werte enthielt, und verwenden Sie eine Methode (of ArrayCollectionfalls vorhanden, oder ein isoliertes Verfahren wie Ihres), um die Werte eines anderen vorhandenen hinzuzufügen ArrayCollection. Ihre Lösung erfordert die Erstellung einer neuen ArrayCollection, was den Prozess schwer macht. Danke trotzdem!

    – Schlucken

    10. April 2012 um 6:00 Uhr


  • Das & ist eine Referenzübergabe, da Sie die Argumente nicht ändern möchten. Sie könnten die Methode umschreiben, um stattdessen die Sammlungen zu durchlaufen. Für diese Methode gibt es keine Argumente, sodass Sie beliebig viele Sammlungen kombinieren können.

    – Stephen Senkomago Musoke

    10. April 2012 um 6:05 Uhr

  • Die Sache ist, ich bekomme meine Quellsammlungen dynamisch, also kann ich den Aufruf nicht so machen, wie Sie es vorschlagen …

    – Schlucken

    10. April 2012 um 6:11 Uhr

  • Was ich meinte, ist, dass Sie eine Methode mergeCollections ($collection1, $collection2) schreiben können, die den Inhalt von $collection2 in $collection1 zusammenführt. Sie können die Funktion mergeCollection an anderer Stelle in Ihrer Anwendung wiederverwenden

    – Stephen Senkomago Musoke

    10. April 2012 um 6:20 Uhr

  • Sie sollten stattdessen array_merge() verwenden.

    – Daniel Ribeiro

    10. April 2012 um 14:20 Uhr

Fügen Sie eine Sammlung zu einem Array hinzu, basierend auf Yury Pliashkous Kommentar (ich weiß, dass die ursprüngliche Frage nicht direkt beantwortet wird, aber das wurde bereits beantwortet, und dies könnte anderen helfen, hier zu landen):

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;
}

Vielleicht gefällt es dir … vielleicht auch nicht … Ich dachte nur daran, es rauszuschmeißen, falls jemand es braucht.

  • Was ist das & Betreiber für? ist es so etwas wie in C? Nun, das ist natürlich eine Lösung, aber das Verhalten, das ich erwartet hatte, war eine ArrayCollection die bereits einige Werte enthielt, und verwenden Sie eine Methode (of ArrayCollectionfalls vorhanden, oder ein isoliertes Verfahren wie Ihres), um die Werte eines anderen vorhandenen hinzuzufügen ArrayCollection. Ihre Lösung erfordert die Erstellung einer neuen ArrayCollection, was den Prozess schwer macht. Danke trotzdem!

    – Schlucken

    10. April 2012 um 6:00 Uhr


  • Das & ist eine Referenzübergabe, da Sie die Argumente nicht ändern möchten. Sie könnten die Methode umschreiben, um stattdessen die Sammlungen zu durchlaufen. Für diese Methode gibt es keine Argumente, sodass Sie beliebig viele Sammlungen kombinieren können.

    – Stephen Senkomago Musoke

    10. April 2012 um 6:05 Uhr

  • Die Sache ist, ich bekomme meine Quellsammlungen dynamisch, also kann ich den Aufruf nicht so machen, wie Sie es vorschlagen …

    – Schlucken

    10. April 2012 um 6:11 Uhr

  • Was ich meinte, ist, dass Sie eine Methode mergeCollections ($collection1, $collection2) schreiben können, die den Inhalt von $collection2 in $collection1 zusammenführt. Sie können die Funktion mergeCollection an anderer Stelle in Ihrer Anwendung wiederverwenden

    – Stephen Senkomago Musoke

    10. April 2012 um 6:20 Uhr

  • Sie sollten stattdessen array_merge() verwenden.

    – Daniel Ribeiro

    10. April 2012 um 14:20 Uhr

Aufmerksamkeit! Vermeiden Sie große Verschachtelungen rekursiver Elemente. array_unique hat eine rekursive Einbettungsgrenze und verursacht a PHP 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);

1353130cookie-checkWie man zwei PHP Doctrine 2 ArrayCollection() zusammenführt

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy