如何重新排序集合

时间:2015-07-13 18:33:21

标签: cakephp collections cakephp-3.0

来自以下查询:

$unlocked_ags = $this->Deviceconnections->find()
            ->contain(['Agthemes.Sites'])
            ->where(['request' => 'unlock'])->all();

我得到以下结果。我只保留了有用的信息。

'items' => [
    (int) 0 => object(App\Model\Entity\Deviceconnection) {

        'id' => (int) 196,
        'agtheme' => object(App\Model\Entity\Agtheme) {

            'id' => (int) 49,
            'site' => object(App\Model\Entity\Site) {

                'id' => (int) 5510,
            },
        },
    },
    (int) 1 => object(App\Model\Entity\Deviceconnection) {

        'id' => (int) 197,
        'agtheme' => object(App\Model\Entity\Agtheme) {

            'id' => (int) 44,
            'site' => object(App\Model\Entity\Site) {

                'id' => (int) 64,
            },
        },
    },
    (int) 2 => object(App\Model\Entity\Deviceconnection) {

        'id' => (int) 198,
        'agtheme' => object(App\Model\Entity\Agtheme) {

            'id' => (int) 49,
            'site' => object(App\Model\Entity\Site) {

                'id' => (int) 5510,
                },
            },
        },
    },
    (int) 3 => object(App\Model\Entity\Deviceconnection) {

        'id' => (int) 199,
        'agtheme' => object(App\Model\Entity\Agtheme) {

            'id' => (int) 44,
            'site' => object(App\Model\Entity\Site) {

                'id' => (int) 5682,
                },
            },
        },
    },
    (int) 4 => object(App\Model\Entity\Deviceconnection) {

        'id' => (int) 200,
        'agtheme' => object(App\Model\Entity\Agtheme) {

            'id' => (int) 44,
            'site' => object(App\Model\Entity\Site) {

                'id' => (int) 5682,
                },
            },
        },
    },
    (int) 5 => object(App\Model\Entity\Deviceconnection) {

        'id' => (int) 201,
        'agtheme' => object(App\Model\Entity\Agtheme) {

            'id' => (int) 49,
            'site' => object(App\Model\Entity\Site) {

                'id' => (int) 5510,
                },
            },
        },
    },
    (int) 6 => object(App\Model\Entity\Deviceconnection) {

        'id' => (int) 202,
        },
        'agtheme' => object(App\Model\Entity\Agtheme) {

            'id' => (int) 40,
            },
            'site' => object(App\Model\Entity\Site) {

                'id' => (int) 64,
                },
            },
        },
    }
]

但实际上我希望按网站和agtheme列出设备连接列表。

我在查询中完成了一半:

$unlocked_ags = $this->Deviceconnections->find()
            ->contain(['Agthemes.Sites'])
            ->where(['request' => 'unlock'])
            ->groupBy('agtheme.site.id');

允许我按网站分组。

我需要类似的东西:

$unlocked_ags = $this->Deviceconnections->find()
            ->contain(['Agthemes.Sites'])
            ->where(['request' => 'unlock'])
            ->groupBy('agtheme.site.id')
            ->groupBy('agtheme.id');

但似乎我需要以不同的方式编写它。

怎么做?

修改 我尝试过类似的东西:

    $unlocked_ags = $this->Deviceconnections->find()
            ->contain(['Agthemes.Sites'])
            ->where(['request' => 'unlock']);

    $unlocked_ags = $unlocked_ags->groupBy('agtheme.site.id');
    $unlocked_ags = new Collection($unlocked_ags);
    $unlocked_ags = $unlocked_ags->groupBy('agtheme.id');

这正确地创建了分组数组,但不幸的是,这使得索引松散。

结果如下:

[
    '' => [
        (int) 0 => [
            (int) 0 => object(App\Model\Entity\Deviceconnection) {
            ...

这很可惜,因为如果我这样做:

    $unlocked_ags = $this->Deviceconnections->find()
            ->contain(['Agthemes.Sites'])
            ->where(['request' => 'unlock']);

    $unlocked_ags = $unlocked_ags->groupBy('agtheme.site.id');

我明白了:

[
    (int) 5510 => [
        (int) 0 => object(App\Model\Entity\Deviceconnection) {
         ...

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

如果您想要嵌套结果,您必须迭代第一个分组结果并再次对它们进行分组:

->groupBy('agtheme.site.id')
->map(function ($data) {
    return collection($data)->groupBy('agtheme.site')->toArray();
})

或使用回调基于多个字段创建自定义标识符,如:

->groupBy(function($row) {
    return $row['agtheme']['id'] . ',' . $row['agtheme']['site']['id'];
})

后者会创建像49,5510这样的字符串索引,所以在访问/迭代结果时要小心!

另请参阅 API > \Cake\Collection\CollectionInterface::groupBy()