두 개의 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 }

두 번째 컬렉션을 반복하고 각 요소를 첫 번째 컬렉션에 하나씩 추가 할 수 있는지 알고 싶습니다.

감사!


3
일반적이고 필요한 방법이기 때문에 +1
JavierIEH

답변:


171

나를 위해 더 나은 (그리고 작동하는) 변형 :

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

최고의 답변입니다.
carles 2013-08-23

나는이 솔루션을 권장
ioleo

나는 똑같이하려고하지만 배열로 : array_merge ($ merged_arr, $ doct_collection-> toArray ()); 하지만 오류가 발생하지 않거나 작동하지 않습니다 ($ merged_arr가 비어 있음). 어떤 아이디어?
Guy

5
아마도 $ merged_arr = array_merge ($ merged_arr, $ doct_collection-> toArray ())?
pliashkou

12

간단하게 다음을 수행 할 수 있습니다.

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

6
나는 이것이 왜 그렇게 많은 찬성표를 얻는 지 이해하지 못합니다. 그것은 단순히 잘못된 것입니다. 객체를 배열로 캐스트하면 toArray(). 무슨 일이 일어나는지 확인하십시오
greg0ire 2013-06-13

21
폭도들의 사고 방식은 항상 재미 있지만, 당신 중 누구라도 실제로 그것을 하향 표하기 전에 이것을 시도 했습니까? ArrayCollection은 컬렉션을 배열로 캐스팅 할 수있는 IteratorAggregate를 구현하며 예상대로 작동합니다.
Lewis

5
똑똑한 사람, 하느님 감사합니다!
Daniel Ribeiro 2014

1
@Lewis : 그것은 전에 그것을 망쳤습니다. 그건 내가 다른 변형을 작성해야했습니다 이유
pliashkou

2
@Lewis : 파티에 조금 늦었지만 그 문제로 돌아오고 있습니다. 그래도 시도했지만 작동하지 않습니다.
greg0ire 2015 년

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

네,하지만 이것과 같은 일을하는 다른 인기있는 대답은 전체 모델 객체를 배열로 변환하여 추가 기능을 제한합니다.
zeros-and-ones

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

이것은보다 빠릅니다 array_merge. 에 $collection1동일한 키 이름이 있으면의 중복 키 이름 이 유지됩니다 $collection2. 실제 가치가 무엇이든


toArray()배열을 반환합니다. 다른 유형의 힌트를 array확실하게 입력 할 필요가 없습니까 ?
Jimbo

@jimbo : 당신 말이 맞지만 어떤 이유로 든 첫 번째 $collection->toArray()null또는 false. 치명적인 오류가 발생합니다.
kanariezwart

공정한 점-Doctrine이 배열로 변환하는 데 실패하면 Doctrine 코드베이스에 문제가있는 것입니다.)
Jimbo

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프로세스가 무겁습니다. 어쨌든 감사합니다!
Throoze

&는 인수를 변경하지 않기 때문에 참조에 의한 전달입니다. 대신 컬렉션을 반복하도록 메서드를 다시 작성할 수 있습니다. 이 메서드에는 인수가 없으므로 원하는만큼 많은 컬렉션을 결합 할 수 있습니다.
Stephen Senkomago Musoke 2012

문제는 내 소스 컬렉션을 동적으로 가져
오므로

내가 의미하는 것은 당신이 어디에 응용 프로그램 내에서 그렇지 않으면 mergeCollection 기능을 다시 사용할 수 있습니다 $ collection1에 $ collection2의 내용을 병합하는 방법의 mergeCollections ($ collection1, $ collection2) 쓸 수 있다는 점이다
스티븐 Senkomago 무소

대신 array_merge ()를 사용해야합니다.
Daniel Ribeiro

0

Yury Pliashkou 의 의견을 기반으로 컬렉션을 배열에 추가합니다 (원래 질문에 직접 답변하지는 않지만 이미 답변을 받았으므로 다른 사람들이 여기에 도착하는 데 도움이 될 수 있음) :

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
나는 다른 사람들처럼 컬렉션을 배열에 추가해야 할 때이 질문에 착수했지만 내 유스 케이스는 빈 배열 / 컬렉션을 확인해야했기 때문에 여기에서 공유했습니다.
Manatax

0

주의! 재귀 요소의 큰 중첩을 피하십시오.array_unique - 재귀 삽입 한계가 있고 원인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);

-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();. 또한 마지막 출력은 코드 형식이어야합니다.
k00ni
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.