2012-04-10 110 views
66

有没有什么方便的方法可以连接两个Doctrine ArrayCollection()?像这样:如何合并两个PHP Doctrine 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 } 

我只想知道,如果我可以救我迭代第二集合,并逐一添加到第一集合的每个元素。

谢谢!

+3

+1,因为它是一个共同的,需要方法 – JavierIEH 2012-10-02 14:40:39

回答

129

更好的(和工作)变种我:

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

最好的答案,毫无疑问。 – carles 2013-08-23 07:30:28

+0

我推荐这个解决方案 – loostro 2013-09-19 10:18:31

+0

我试图做同样的事情,但进入一个数组:array_merge($ merged_arr,$ doct_collection-> toArray());但没有得到一个错误或它是否工作($ merged_arr是空的)。有任何想法吗? – Guy 2013-10-20 18:34:50

1

您仍然需要遍历集合以将一个数组的内容添加到另一个。由于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; 
} 
+0

什么是'&'运营商?这是像C中的东西吗?当然这是一个解决方案,但是我期望的行为是拥有一个已经包含一些值的'ArrayCollection',并且使用一个方法(如果存在'ArrayCollection',或者像你一样的孤立过程)添加另一个现有的'ArrayCollection'的值。你的解决方案需要创建一个新的'ArrayCollection',这使得这个过程变得沉重。不管怎么说,还是要谢谢你! – Throoze 2012-04-10 06:00:00

+0

由于您不想更改参数,所以&是通过引用传递。您可以重写该方法以迭代集合。这种方法没有任何参数,因此您可以根据需要组合任意数量的集合。 – 2012-04-10 06:05:41

+0

问题是,我动态获取源集合,因此无法按照您的建议进行调用... – Throoze 2012-04-10 06:11:15

13

你可以简单地这样做:

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

我不明白为什么会得到这么多upvotes。这完全是错误的。将对象转换为数组不会调用'toArray()'。 [看看会发生什么](http://www.php.net/manual/en/language.types.array.php#language.types.array.casting) – greg0ire 2013-06-13 14:45:51

+0

这不起作用 – 2013-09-20 07:28:18

+16

虽然小鬼的心态总是很有趣,在你投票之前,你们有没有真的尝试过这个? ArrayCollection实现了IteratorAggregate,它允许您将集合转换为数组,并且它将像预期的那样工作。 – Lewis 2014-04-09 13:47:44

1

基于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; 
} 

也许你喜欢它......也许不是......我只是想把它扔到那里以防万一有人需要它。

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

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

+0

'toArray()'返回一个数组,你不应该需要键入另一个'数组'''当然? – Jimbo 2015-04-29 13:08:23

+0

@jimbo:你是对的,但如果因为任何原因,第一个'$ collection-> toArray()'返回'null'或'false'。你最终会有一个致命的错误。 – kanariezwart 2016-10-31 09:47:48

+0

公平点 - 虽然如果教义未能转换为数组,那么教义代码库就会出现严重错误;) – Jimbo 2016-10-31 11:28:29

7

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

在某些情况下可能会得心应手。

0

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