Czy jest jakaś wygodna metoda, która pozwala mi połączyć dwie doktryny ArrayCollection()
? coś jak:
$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 }
Chcę tylko wiedzieć, czy mogę zaoszczędzić sobie na iterowaniu drugiej kolekcji i dodawaniu każdego elementu jeden po drugim do pierwszej kolekcji.
Dzięki!
php
symfony
doctrine-orm
arraycollection
Throoze
źródło
źródło
Odpowiedzi:
Dla mnie lepszy (i działający) wariant:
$collection3 = new ArrayCollection( array_merge($collection1->toArray(), $collection2->toArray()) );
źródło
Możesz po prostu zrobić:
$a = new ArrayCollection(); $b = new ArrayCollection(); ... $c = new ArrayCollection(array_merge((array) $a, (array) $b));
źródło
toArray()
. Zobacz, co się stanieJeśli musisz zapobiegać duplikatom, ten fragment może pomóc. Używa wariadycznego parametru funkcji do użycia z 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; }
Może się przydać w niektórych przypadkach.
źródło
$collection3 = new ArrayCollection(array_unique(array_merge($collection1->toArray(), $collection2->toArray())));
$newCollection = new ArrayCollection((array)$collection1->toArray() + $collection2->toArray());
To powinno być szybsze niż
array_merge
. Zduplikowane nazwy kluczy z$collection1
są zachowywane, gdy ta sama nazwa klucza jest obecna w$collection2
. Bez względu na rzeczywistą wartośćźródło
toArray()
zwraca tablicę, naarray
pewno nie musisz wpisywać innej wskazówki ?$collection->toArray()
wracanull
lubfalse
. Kończy się fatalnym błędem.Nadal musisz iterować kolekcje, aby dodać zawartość jednej tablicy do drugiej. Ponieważ ArrayCollection jest klasą opakowującą, możesz spróbować scalić tablice elementów przy jednoczesnym zachowaniu kluczy, klucze tablic w $ collection2 przesłaniają wszelkie istniejące klucze w $ collection1 przy użyciu funkcji pomocniczej poniżej:
$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; }
źródło
&
operator? czy to jest jak w C? Cóż, oczywiście jest to rozwiązanie, ale zachowanie, którego się spodziewałem, polegało na tym, że miałbym miećArrayCollection
już jakieś wartości i użyć metody (ArrayCollection
jeśli istnieje, lub izolowanej procedury, takiej jak twoja), aby dodać wartości innej istniejącejArrayCollection
. Twoje rozwiązanie wymaga stworzenia nowegoArrayCollection
, co utrudnia proces. W każdym razie dzięki!Dodaj kolekcję do tablicy, na podstawie komentarza Yury Pliashkou (wiem, że nie odpowiada on bezpośrednio na pierwotne pytanie, ale na to już udzielono odpowiedzi, a to może pomóc innym wylądować tutaj):
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; }
Może ci się podoba ... może nie ... Pomyślałem o wyrzuceniu tego na wypadek, gdyby ktoś tego potrzebował.
źródło
Uwaga! Unikaj dużego zagnieżdżania elementów rekurencyjnych. array_unique - ma rekurencyjny limit osadzania i powoduje, że
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);
źródło
Korzystanie z 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
źródło
echo $a.toArray();
z pewnością zgłosi błąd, ponieważtoArray
nie jest prawidłową funkcją. Musi być przynajmniejecho $a->toArray();
. Ponadto wynik końcowy powinien być sformatowany jako kod.