96 votes

Comment fusionner deux ArrayCollection() en php Doctrine 2

Existe-t-il une méthode pratique qui me permette de concaténer deux Doctrine ArrayCollection() ? quelque chose comme :

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

Je veux juste savoir si cela peut m'éviter d'itérer sur la 2ème collection et d'ajouter chaque élément un par un à la 1ère collection.

Gracias.

3 votes

+1 parce que c'est une méthode courante et nécessaire

196voto

Yury Pliashkou Points 791

Meilleure variante (et qui fonctionne) pour moi :

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

0 votes

La meilleure réponse, sans aucun doute.

0 votes

Je recommande cette solution

0 votes

J'essaie de faire la même chose mais dans un tableau : array_merge($merged_arr, $doct_collection->toArray()) ; mais je n'obtiens pas d'erreur ou cela fonctionne ($merged_arr est vide). Avez-vous une idée ?

15voto

Daniel Ribeiro Points 3546

Vous pouvez simplement le faire :

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

6 votes

Je ne comprends pas pourquoi il y a autant de votes positifs. C'est tout simplement faux. Transférer un objet dans un tableau ne fait pas appel à la fonction toArray() . Voir ce qui se passe

22 votes

Bien que la mentalité de la foule soit toujours amusante, est-ce que l'un d'entre vous a vraiment essayé avant de le descendre ? ArrayCollection implémente IteratorAggregate, ce qui vous permet de transformer la collection en un tableau et cela fonctionnera comme prévu.

5 votes

Dieu merci, quelqu'un d'intelligent !

11voto

Matthias Brock Points 183

Si vous devez éviter les doublons, cet extrait de code peut vous aider. Il utilise un paramètre de fonction variadique pour une utilisation avec 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;
}

Cela peut être utile dans certains cas.

2 votes

Ou utilisez $collection3 = new ArrayCollection(array_unique(array_merge($collection1->toArr‌​ay(), $collection2->toArray())));

1 votes

Oui, mais cette réponse et l'autre réponse populaire qui fait la même chose convertissent l'objet modèle entier en tableaux, ce qui limite la fonctionnalité ultérieure.

4voto

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

Cela devrait être plus rapide que array_merge . Duplication des noms de clés de $collection1 sont conservés lorsque le même nom de clé est présent dans $collection2 . Peu importe ce que la valeur réelle est

0 votes

toArray() renvoie un tableau, vous ne devriez pas avoir besoin de taper un autre typehint array sûrement ?

0 votes

@jimbo : vous avez raison, mais si pour une raison quelconque le premier $collection->toArray() renvoie à null o false . Vous vous retrouvez avec une erreur fatale.

0 votes

C'est vrai - mais si Doctrine ne parvient pas à convertir en tableau, alors quelque chose ne tourne pas rond dans le code de Doctrine ;)

2voto

ssmusoke Points 1990

Vous devez toujours itérer sur les collections pour ajouter le contenu d'un tableau à un autre. Puisque ArrayCollection est une classe d'enveloppe, vous pouvez essayer de fusionner les tableaux d'éléments tout en conservant les clés, les clés du tableau dans $collection2 remplacent toutes les clés existantes dans $collection1 en utilisant une fonction d'aide ci-dessous :

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

0 votes

Quel est le & Est-ce que c'est quelque chose comme en C ? Bien sûr, c'est une solution, mais le comportement que j'attendais était d'avoir un opérateur ArrayCollection qui contenait déjà certaines valeurs, et utiliser une méthode (de type ArrayCollection si elle existe, ou une procédure isolée, comme la vôtre) pour ajouter les valeurs d'une autre procédure existante ArrayCollection . Votre solution nécessite la création d'un nouveau ArrayCollection ce qui rend le processus lourd. Merci quand même !

0 votes

Le & est une passe par référence, puisque vous ne voulez pas changer les arguments. Vous pourriez réécrire la méthode pour itérer sur les collections à la place. Il n'y a pas d'arguments pour cette méthode, vous pouvez donc combiner autant de collections que vous le souhaitez.

0 votes

Le problème, c'est que j'obtiens mes collections de sources de façon dynamique, donc je ne peux pas faire l'appel comme vous le suggérez...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X