Cách hợp nhất hai php Doctrine 2 ArrayCollection ()


80

Có phương pháp tiện lợi nào cho phép tôi nối hai Doctrine ArrayCollection()không? cái gì đó như:

$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 việc lặp lại 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ì một chung và phương pháp cần thiết
JavierIEH

Câu trả lời:


168

Biến thể tốt hơn (và đang hoạt động) đối với tôi:

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

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

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

Tôi đang cố gắng làm điều tương tự nhưng vào một mảng: array_merge ($ merge_arr, $ doct_collection-> toArray ()); nhưng không gặp lỗi hoặc nó đang hoạt động ($ merge_arr trống). Có ý kiến ​​gì không?
Guy

5
Có thể $ merge_arr = array_merge ($ merge_arr, $ doct_collection-> toArray ())?
pliashkou

12

Bạn chỉ cần làm:

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

6
Tôi không hiểu tại sao điều này lại nhận được nhiều ủng hộ đến vậy. Nó chỉ đơn giản là sai. Truyền một đối tượng vào một mảng không gọi toArray(). Xem những gì xảy ra
greg0ire

21
Trong khi tâm lý đám đông luôn vui vẻ, có ai trong số các bạn thực sự thử điều này trước khi từ chối nó không? ArrayCollection thực hiện IteratorAggregate cho phép bạn ép kiểu tập hợp dưới dạng một mảng và nó sẽ hoạt động như mong đợi.
Lewis

5
Cảm ơn Chúa, một người thông minh!
Daniel Ribeiro

1
@Lewis: Nó đã xé nó trước đây, nó không hoạt động với tôi (tôi không có thời gian để làm điều đó). Đó là lý do tại sao tôi đã phải viết biến thể khác
pliashkou

2
@Lewis: đến bữa tiệc hơi muộn, nhưng tôi đang quay lại vấn đề đó, và vâng, tôi đã thử nó, và không, nó không hoạt động, do đó là downvote.
greg0ire,

10

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 đa dạng để 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.


1
Hoặc sử dụng$collection3 = new ArrayCollection(array_unique(array_merge($collection1->toArray(), $collection2->toArray())));
spdionis

Vâng, nhưng câu trả lời này và câu trả lời phổ biến khác có cùng chức năng chuyển đổi toàn bộ đối tượng mô hình thành mảng, điều này giới hạn chức năng hơn nữa.
số không-và-cái,

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

Điều này sẽ nhanh hơn array_merge. Các tên khóa trùng lặp từ $collection1được giữ lại khi có cùng một tên khóa $collection2. Bất kể giá trị thực tế là bao nhiêu


toArray()trả về một mảng, arraychắc chắn bạn không cần phải gõ chữ khác ?
Jimbo

@jimbo: bạn nói đúng, nhưng nếu vì bất kỳ lý do gì mà lần đầu tiên $collection->toArray()trả về nullhoặc false. Bạn sẽ gặp một lỗi nghiêm trọng.
kanariezwart,

Fair điểm - mặc dù nếu học thuyết không chuyển đổi sang một mảng sau đó một cái gì đó là tồi tệ xảy ra với các học thuyết codebase;)
Jimbo

2

Bạn vẫn cần phải lặp lại các Bộ sưu tập để thêm nội dung của mảng này vào mảng khác. Vì ArrayCollection là một lớp trình bao bọc, bạn có thể thử hợp nhất các mảng phần tử trong khi vẫn duy trì các khóa, các khóa mảng trong $ collection2 ghi đè bất kỳ khóa hiện có nào trong $ collection1 bằng cách sử dụng hàm trợ giúp bên dưới:

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

Nhà &điều hành để làm gì? 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 mà tôi mong đợi là có một ArrayCollectiongiá trị đã 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, như của bạn) để thêm các giá trị của một ArrayCollection. Giải pháp của bạn yêu cầu tạo mới ArrayCollection, điều này làm cho quá trình trở nên nặng nề. Dù sao cũng cảm ơn bạn!
Throoze

& Là một tham chiếu chuyển qua, vì bạn không muốn thay đổi các đối số. Thay vào đó, bạn có thể viết lại phương thức để lặp lại các bộ sưu tập. Không có đối số nào đối với phương pháp này nên bạn có thể kết hợp bao nhiêu tập hợp tùy thích.
Stephen Senkomago Musoke,

Có điều là, tôi nhận được bộ sưu tập nguồn của tôi tự độ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

Những gì tôi có nghĩa là bạn có thể viết một phương pháp mergeCollections ($ collection1, $ collection2) mà kết hợp các nội dung của $ collection2 thành $ collection1 bạn có thể tái sử dụng các chức năng khác mergeCollection nơi trong phạm vi ứng dụng của bạn
Stephen Senkomago Musoke

Thay vào đó, bạn nên sử dụng array_merge ().
Daniel Ribeiro

0

Thêm Bộ sưu tập vào một mảng, dựa trên nhận xét của Yury Pliashkou (Tôi biết nó không trả lời trực tiếp câu hỏi ban đầu, nhưng câu đó đã được trả lời và điều này có thể giúp những người khác đến đây):

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 đó phòng khi ai đó cần nó.


Luôn luôn tốt khi có một số loại đa dạng trong các giải pháp khả thi. Nhưng so với những người khác, tôi không thấy lợi ích khi sử dụng giải pháp của bạn. Bạn có vui lòng mô tả nó chi tiết hơn một chút không?
k00ni

1
Tôi đã đặt ra câu hỏi này khi cần thêm bộ sưu tập vào một mảng, như một số người khác, nhưng trường hợp sử dụng của tôi yêu cầu kiểm tra mảng / bộ sưu tập trống, vì vậy tôi đã chia sẻ nó ở đây.
Manatax

0

Chú ý! Tránh lồng ghép lớn các phần tử đệ quy. array_unique - có giới hạn nhúng đệ quy và gây raPHP 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

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

Gợi ý nhỏ : Phần echo $a.toArray();chắc chắn sẽ gặp lỗi, vì toArraykhông phải là một hàm hợp lệ. Nó phải là ít nhất echo $a->toArray();. Hơn nữa, đầu ra cuối cùng nên được định dạng dưới dạng mã.
k00ni
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.