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

问题描述 投票:0回答:10

有什么方便的方法可以让我连接两个 Doctrine

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 }

我只是想知道是否可以省去迭代第二个集合并将每个元素一一添加到第一个集合的麻烦。

谢谢!

php symfony doctrine-orm arraycollection
10个回答
190
投票

对我来说更好(且有效)的变体:

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

15
投票

你可以简单地做:

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

11
投票

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

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


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

这应该比

array_merge
更快。当
$collection1
中存在相同的键名称时,将保留
$collection2
中的重复键名称。不管实际价值是多少


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

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

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


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

0
投票

结合展开运算符来合并多个集合,例如电子表格的所有工作表中的所有行,其中 $sheets 和 $rows 都是 ArrayCollections 并具有 getRows(): Collection 方法

// Sheet.php
public function getRows(): Collection { return $this->rows; }

// Spreadsheet.php
public function getSheets(): Collection { return $this->sheets; }

public function getRows(): Collection
     return array_merge(...$this->getSheets()->map(
        fn(Sheet $sheet) => $sheet->getRows()->toArray()
     ));

0
投票

要获得独特的收藏:

$uniqueCollection = new ArrayCollection(array_unique(array_merge(
    $collectionA->toArray(),
    $collectionB->toArray()
), SORT_REGULAR));

-2
投票

使用闭包 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
© www.soinside.com 2019 - 2024. All rights reserved.