具有联接的多维数组结果


Multidimensional array results with joins

我正在联接表,我想根据联接获得多维查询结果。

# AppBundle:ProductRepository
$this->createQueryBuilder('pr')
    ->select('pk.id', 'pk.name', 'pr.id', 'pr.label')
    ->join('pr.package', 'pk')
    ->getQuery()->getResult();

如您所见,Product链接到Package(多对一)

这是我得到的结果:

array(
    array('id' => '1', 'name' => 'package 1', 'id1' => 1, 'label' => 'product 1'),
    array('id' => '1', 'name' => 'package 1', 'id1' => 2, 'label' => 'product 2'),
    array('id' => '2', 'name' => 'package 2', 'id1' => 3, 'label' => 'product 3'),
)

以下是我想要的:

array(
    array(
        'id' => '1',
        'name' => 'package 1',
        'products' => array(
            array(
                'id' => 1,
                'label' => 'product 1',
            ),
            array(
                'id' => 2,
                'label' => 'product 2',
            ),
        ),
    ),
    array(
        'id' => '2',
        'name' => 'package 2',
        'products' => array(
            array(
                'id' => 3,
                'label' => 'product 3',
            ),
        ),
    ),
)

有没有一种方法可以用条令2来水合这种多维数组?

我的意思是使用Doctrine 2,而不是"post-prod"php循环

您需要将部分结果与数组水合器相结合。尝试:

$this->createQueryBuilder('pr')
    ->select('partial pk.{id, name}, partial pr.{id, label}')
    ->join('pr.package', 'pk')
    ->getQuery()
    ->getArrayResult()
;

首先需要使用部分结果并对一对多关系进行建模。示例:

在您的控制器中:

$qb = $em->createQueryBuilder()
      ->select('partial author.{id, name}, partial articles.{id, title, content}')
      ->from('Module'Model'Author', 'author')
      ->leftJoin('author.articles', 'articles');
$query = $qb->getQuery();
$results = $query->getArrayResult();

不要忘记使用OneToMany关系。http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-到许多双向

因此,在Author.php模型中写下:

/**
 * @ORM'OneToMany(targetEntity="Articles", mappedBy="author")
 */
private $articles;
public function __construct() {
    $this->articles = new ArrayCollection();
}

我制作了一些小算法,将数据连接到您描述的表单中。

$source = array(
    array('id' => '1', 'name' => 'package 1', 'id1' => 1, 'label' => 'product 1'),
    array('id' => '1', 'name' => 'package 1', 'id1' => 2, 'label' => 'product 2'),
    array('id' => '2', 'name' => 'package 2', 'id1' => 3, 'label' => 'product 3'),
);
// Here is what I'd like to get:
$target = array(
    array(
        'id' => '1',
        'name' => 'package 1',
        'products' => array(
            array(
                'id' => 1,
                'label' => 'product 1',
            ),
            array(
                'id' => 2,
                'label' => 'product 2',
            ),
        ),
    ),
    array(
        'id' => '2',
        'name' => 'package 2',
        'products' => array(
            array(
                'id' => 3,
                'label' => 'product 3',
            ),
        ),
    ),
);
// id => item
$map = array();
foreach($source as $item)
{
    // prepare product
    $product = array(
        'id' => $item['id1'],
        'label' => $item['label'],
    );
    if (isset($map[$item['id']]))
    {
        // push data to existing item in $map
        $map[$item['id']]['products'][] = $product;
    }
    else
    {
        // create new item in $map
        $map[$item['id']] = array(
            'id' => $item['id'],
            'name' => $item['name'],
            'products' => array($product),
        );
    }
}
function array_diff_assoc_recursive($array1, $array2) {
    $difference=array();
    foreach($array1 as $key => $value) {
        if( is_array($value) ) {
            if( !isset($array2[$key]) || !is_array($array2[$key]) ) {
                $difference[$key] = $value;
            } else {
                $new_diff = array_diff_assoc_recursive($value, $array2[$key]);
                if( !empty($new_diff) )
                    $difference[$key] = $new_diff;
            }
        } else if( !array_key_exists($key,$array2) || $array2[$key] !== $value ) {
            $difference[$key] = $value;
        }
    }
    return $difference;
}
$new = array_values($map);
var_export($new);
echo "'ndiff: ";
$diff = array_diff_assoc_recursive($target, $new);
var_export($diff);

函数array_diff_assoc_recrasive在这里借用了Gioshhttp://php.net/manual/en/function.array-diff-assoc.php