2つのphpDoctrine 2 ArrayCollection()をマージする方法


82

2つの教義を連結できる便利な方法はあります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 2012年

回答:


171

私にとってより良い(そして機能する)バリアント:

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

間違いなくベストアンサー。
carles 2013

私はこの解決策をお勧めします
ioleo 2013

私は同じことをしようとしていますが、配列に入れています:array_merge($ merged_arr、$ doct_collection-> toArray()); ただし、エラーが発生していないか、機能していますか($ merged_arrは空です)。何か案は?
ガイ

5
たぶん$ merged_arr = array_merge($ merged_arr、$ doct_collection-> toArray())?
pliashkou 2013年

12

あなたは簡単に行うことができます:

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

6
なぜこれほど多くの賛成票が得られるのかわかりません。それは単に間違っています。オブジェクトを配列にキャストしても、は呼び出されませんtoArray()何が起こるかを見てください
greg0ire 2013年

21
暴徒のメンタリティは常に楽しいものですが、反対票を投じる前に実際にこれを試した人はいますか?ArrayCollectionは、コレクションを配列としてキャストできるIteratorAggregateを実装しており、期待どおりに機能します。
ルイス

5
賢い人、神に感謝します!
ダニエル・リベイロ

1
@ルイス:それは前にそれを乾かしました、それは私のために働きませんでした(私はそれに入る時間がありませんでした)。そのため、別のバリアントを作成する必要がありました
pliashkou 2015

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 2018年

ええ、でもこれと同じことをする他の一般的な答えは、モデルオブジェクト全体を配列に変換します。これにより、それ以上の機能が制限されます。
ゼロ

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

これはより高速である必要がありますarray_merge$collection1に同じキー名が存在する場合、からの重複キー名が保持され$collection2ます。実際の値に関係なく


toArray()配列を返します、あなたはarray確かに別のもののタイプヒントをする必要はないはずですか?
ジンボ

@jimbo:あなたは正しいですが、何らかの理由で最初に$collection->toArray()戻るnullfalse。致命的なエラーが発生します。
kanariezwart 2016年

フェアポイント-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があり、プロセスが重くなります。とにかくありがとう!
スローズ2012

引数を変更したくないので、&は参照によるパスです。代わりに、コレクションを反復処理するようにメソッドを書き直すことができます。このメソッドには引数がないため、必要な数のコレクションを組み合わせることができます。
Stephen Senkomago Musoke 2012

重要

つまり、$ collection2の内容を$ collection1にマージするメソッドmergeCollections($ collection1、$ collection2)を記述して、mergeCollection関数をアプリケーション内の他の場所で再利用できるということです
Stephen Senkomago Musoke 2012

代わりに、array_merge()を使用する必要があります。
ダニエルリベイロ2012

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.