2012-04-10 43 views
66

Có phương pháp tiện lợi nào cho phép tôi nối hai Doctrine ArrayCollection() không? một cái gì đó như:Làm cách nào để kết hợp hai 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 } 

Tôi chỉ muốn biết liệu tôi có thể lưu tôi lặp lại trên bộ sưu tập thứ 2 và thêm từng phần tử một vào bộ sưu tập thứ nhất hay không.

Cảm ơn!

+3

+1 vì nó là một phương pháp phổ biến và cần thiết – JavierIEH

Trả lời

129

Better (và làm việc) biến thể cho tôi:

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

Câu trả lời hay nhất, không nghi ngờ gì. – carles

+0

Tôi khuyên bạn nên giải pháp này – loostro

+0

Tôi đang cố gắng làm tương tự nhưng vào một mảng: array_merge ($ merged_arr, $ doct_collection-> toArray()); nhưng không nhận được một lỗi hoặc là nó làm việc ($ merged_arr là sản phẩm nào). Bất kỳ ý tưởng? – Guy

1

Bạn vẫn cần phải lặp qua Bộ sưu tập để thêm nội dung của một mảng vào mảng khác. Kể từ khi ArrayCollection là một lớp wrapper, bạn có thể thử kết hợp các mảng của các yếu tố trong khi duy trì các phím, các phím mảng trong $ collection2 ghi đè lên bất kỳ phím hiện tại $ collection1 sử dụng một hàm helper dưới đây:

$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ác '& 'nhà điều hành là gì? là nó giống như trong C? Vâng, tất nhiên đây là một giải pháp, nhưng hành vi tôi mong đợi là có một 'ArrayCollection' đã chứa một số giá trị và sử dụng một phương thức (của' ArrayCollection', nếu nó tồn tại hoặc một thủ tục riêng biệt, giống như của bạn) thêm các giá trị của 'ArrayCollection' hiện có khác. Giải pháp của bạn yêu cầu tạo một 'ArrayCollection' mới, làm cho quá trình này trở nên nặng nề. Dù sao cũng cảm ơn bạn! – Throoze

+0

& là một thông qua tham chiếu, vì bạn không muốn thay đổi các đối số. Bạn có thể viết lại phương thức để lặp qua các bộ sưu tập thay thế. Không có đối số nào cho phương thức này để bạn có thể kết hợp nhiều bộ sưu tập như bạn muốn. –

+0

Vấn đề là, tôi lấy các bộ sưu tập nguồn động, vì vậy tôi không thể thực hiện cuộc gọi theo cách bạn gợi ý ... – Throoze

13

Bạn có thể đơn giản làm:

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

Tôi không hiểu tại sao điều này lại nhận được rất nhiều upvotes. Nó chỉ đơn giản là sai. Việc đưa một đối tượng vào một mảng không gọi 'toArray()'. [Xem những gì sẽ xảy ra] (http://www.php.net/manual/en/language.types.array.php#language.types.array.casting) – greg0ire

+0

Điều này không hoạt động –

+16

Trong khi tinh thần di động luôn vui vẻ, đã làm bất kỳ của bạn thực sự cố gắng này trước khi downvoting nó? ArrayCollection thực hiện IteratorAggregate cho phép bạn bỏ bộ sưu tập thành một mảng và nó sẽ hoạt động như mong đợi. – Lewis

1

Dựa trên nhận xét Yury Pliashkou 's:

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

Có thể bạn thích nó ... có thể không ... Tôi chỉ nghĩ đến việc ném nó ra khỏi đó chỉ trong trường hợp ai đó cần nó.

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

Điều này phải nhanh hơn array_merge. Tên khóa trùng lặp từ $collection1 được lưu giữ khi có cùng tên khóa trong $collection2. Bất kể giá trị thực tế là gì

+0

'toArray()' trả về một mảng, bạn không cần phải gõ vào một 'mảng' chắc chắn? – Jimbo

+0

@jimbo: bạn nói đúng, nhưng nếu vì bất kỳ lý do nào thì '$ collection-> toArray()' trả về 'null' hoặc' false'. Bạn kết thúc với một lỗi nghiêm trọng. – kanariezwart

+0

Điểm công bằng - mặc dù nếu Doctrine không chuyển đổi thành mảng thì có điều gì đó sai với mã nguồn Doctrine;) – Jimbo

7

Nếu bạn được yêu cầu để ngăn chặn bất kỳ bản sao nào, đoạn mã này có thể hữu ích. Nó sử dụng một tham số hàm variadic để sử dụng với 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; 
} 

Có thể hữu ích trong một số trường hợp.

0

Sử dụng 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 
Các vấn đề liên quan