如何合并两个php Doctrine 2 ArrayCollection()

如何合并两个php Doctrine 2 ArrayCollection(),php,symfony,doctrine-orm,arraycollection,Php,Symfony,Doctrine Orm,Arraycollection,是否有任何方便的方法允许我连接两个原则ArrayCollection()?比如: $collection1 = new ArrayCollection(); $collection2 = new ArrayCollection(); $collection1->add($obj1); $collection1->add($obj2); $collection1->add($obj3); $collection2->add($obj4); $collection2-&g

是否有任何方便的方法允许我连接两个原则
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 }
我只是想知道我是否可以保存我对第二个集合的迭代,并将每个元素逐个添加到第一个集合中


谢谢

您仍然需要迭代集合,以将一个数组的内容添加到另一个数组中。由于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;
}
您可以简单地执行以下操作:

$a = new ArrayCollection();
$b = new ArrayCollection();
...
$c = new ArrayCollection(array_merge((array) $a, (array) $b));
对我来说更好(且有效)的变体:

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

根据的评论将集合添加到数组中(我知道它没有直接回答原始问题,但已经回答了,这可能有助于其他人在此处登录):

也许你喜欢它。。。也许不是。。。我只是想把它扔出去以防万一有人需要它

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

这应该比
array\u merge
更快。当
$collection2
中存在相同的密钥名称时,将保留
$collection1
中的重复密钥名称。无论实际值是多少

如果需要防止任何重复,此代码段可能会有所帮助。它使用可变函数参数用于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;
}

在某些情况下可能很方便。

使用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

注意!避免递归元素的大嵌套array_unique-具有递归嵌入限制,并导致
PHP错误致命错误:嵌套级别太深-递归依赖?

/**
 * @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);


运算符的作用是什么?是不是有点像C?当然,这是一个解决方案,但我所期望的行为是拥有一个已包含一些值的
ArrayCollection
,并使用一个方法(如果存在
ArrayCollection
,或者像您这样的一个独立过程)来添加另一个现有
ArrayCollection
的值。您的解决方案需要创建一个新的
ArrayCollection
,这会使流程变得繁重。无论如何谢谢你!&是一个传递引用,因为您不想更改参数。您可以重写该方法以迭代集合。此方法没有参数,因此您可以根据需要组合任意多个集合。问题是,我动态获取源集合,因此无法按照您建议的方式进行调用…我的意思是您可以编写一个方法mergeCollections($collection1,$collection2)它将$collection2的内容合并到$collection1中。您可以在应用程序中的其他位置重用mergeCollection函数。相反,您应该使用array_merge()。+1,因为这是一种常见且必需的方法。我不明白为什么这会获得如此多的投票。这完全是错误的。将对象强制转换为数组不会调用
toArray()
。虽然暴民心态总是很有趣,但你们中有人真的在投票否决它之前尝试过吗?ArrayCollection实现了IteratorAggregate,它允许您将集合转换为数组,它将按照预期工作。感谢上帝,聪明人@刘易斯:它以前干过,对我没用(我没时间去干)。这就是为什么我必须再写一篇variant@Lewis:派对有点晚了,但我要回到那个问题上来,是的,我试过了,不,它不起作用,因此投了反对票。毫无疑问,这是最好的答案。我推荐这个解决方案。我正尝试做同样的事情,但却成了一个数组:array\u merge($merged\u arr,$doct\u collection->toArray());但我既没有收到错误,也没有收到正在运行的错误($merged_arr为空)。有什么想法吗?也许$merged\u arr=array\u merge($merged\u arr,$doct\u collection->toArray())?
toArray()
返回一个数组,你不需要键入另一个
数组的提示,当然可以?@jimbo:你是对的,但是如果出于任何原因第一个
$collection->toArray()
返回
null
false
。您最终会遇到一个致命错误。公平点-尽管如果条令无法转换为数组,则条令代码库出现严重错误;)或者使用
$collection3=newarraycollection(array\u unique(array\u merge($collection1->toArray(),$collection2->toArray()))是的,但是这个和另一个流行的答案做同样的事情,将整个模型对象转换为数组,这限制了进一步的功能。在可能的解决方案中有某种多样性总是好的。但与其他解决方案相比,我不认为使用您的解决方案有什么好处。您介意更详细地描述一下吗?与其他人一样,我在需要向数组添加集合时遇到了这个问题,但我的用例需要检查空数组/集合,所以我在这里分享了它。小提示:部分
echo$a.toArray()
肯定会抛出错误,因为
toArray
不是有效的函数。它必须至少是
echo$a->toArray()。此外,最后的输出应格式化为代码。
/**
 * @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);