Laravel 集合类中 GroupBy 方法的使用技巧

翻译 Summer ⋅ 于 2个月前 ⋅ 最后回复由 JackLiang 2天前 ⋅ 1181 阅读 ⋅ 原文地址
这是一篇社区协同翻译的文章,已完成翻译,更多信息请点击 协同翻译介绍

自 Laravel v5.5.29 版本后你可以在 集合 中使用多级分组。让我们来看看这意味着什么,是怎么做到的。

准备

这是一篇关于 Laravel 新特性的文章,但在此之前先让我们看看它以前是什么样的。groupBy 是 Collection 类的一个方法。为了我们的例子我会创建一些数据。Students 将会是已经给定的 User 类的工厂状态。

// 来自 Laravel 的 user 工厂
$factory->define(App\User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
        'remember_token' => str_random(10),
    ];
});

// 我们的新的 students 状态
$factory->state(App\User::class, 'students', function (Faker $faker) {
    return [
        'skilllevel' => collect(['beginner', 'intermediate', 'professional'])->random(),
        'teacher' => collect(['Peter', 'Markus', 'Chris'])->random(),
    ];
});
andy1908 翻译于 2个月前

这个新的状态会为用户表添加一些数据,我们有了 skilllevel 和 teacher 这两个新字段和值。为了方便我们会使用路由回调的方式,这样我们就可以很容易的将结果返回到浏览器。

Route::get('/', function () {

    return $students = factory(User::class)
        ->times(3)
        ->states('students')
        ->make();

});

注意:我们使用了 make 方法而没有使用 create 方法,因为我们还没有建立数据库 。

这样就会生成类似于下面的测试数据。

[
    {
        "name": "Jakayla Leffler",
        "email": "ocie70@example.com",
        "skilllevel": "professional",
        "teacher": "Peter"
    },
    {
        "name": "Gustave Cummings II",
        "email": "crona.alexandrea@example.net",
        "skilllevel": "intermediate",
        "teacher": "Markus"
    },
    {
        "name": "Ms. Ethelyn Bergnaum MD",
        "email": "deckow.kelvin@example.net",
        "skilllevel": "beginner",
        "teacher": "Peter"
    }
]
andy1908 翻译于 2个月前

基础示例

我刚刚说了 类似于 是因为我们在工厂方法里使用了 Faker 包,所以每一个结果都会不一样。下一步我们使用 groupBy 方法,通过 skilllevel 字段把我们的数据分组。

return $students->groupBy('skilllevel');

你会看到在我们的结果中使用了 skilllevel 的值作为了新的键名。

{
    "professional": [
        {
            "name": "Jacquelyn Kilback",
            "email": "christopher55@example.net",
            "skilllevel": "professional",
            "teacher": "Chris"
        }
    ],
    "beginner": [
        {
            "name": "Miss Ophelia Ryan Jr.",
            "email": "pollich.tristin@example.net",
            "skilllevel": "beginner",
            "teacher": "Chris"
        },
        {
            "name": "Furman Hahn",
            "email": "blowe@example.net",
            "skilllevel": "beginner",
            "teacher": "Markus"
        }
    ]
}
andy1908 翻译于 2个月前

一些新的东西

直到这里,还没有什么是新东西。那么我之前讲的新特性是什么呢? Patrizio T. 提交了一个 pull request 所以你可以把集合进行多级分组。为了更好的理解它,让我们来看一个例子。

return $students->groupBy(['skilllevel','teacher']);

为了实现多级分组,我们传递了一个数组参数而不是字符串参数。首先,students 会按 skilllevel 分组,然后再按 teacher 分组。所以我们得到如下结果。

{
    "intermediate": {
        "Peter": [
            {
                "name": "Jana McClure III",
                "email": "oliver.pagac@example.com",
                "skilllevel": "intermediate",
                "teacher": "Peter"
            }
        ],
        "Chris": [
            {
                "name": "Rosemarie Barrows",
                "email": "epurdy@example.com",
                "skilllevel": "intermediate",
                "teacher": "Chris"
            }
        ]
    },
    "professional": {
        "Markus": [
            {
                "name": "Katrine Streich",
                "email": "carlee.koepp@example.com",
                "skilllevel": "professional",
                "teacher": "Markus"
            }
        ]
    }
}

这种分组方式在你想展示或比较数据的时候会很有用。在此例中,只有 Markus 拥有一个 professional 的学生,或许他已经是一个好老师了吧?

andy1908 翻译于 2个月前

变得疯狂点

这对我们的例子来说没有意义的,但我们可以将学生们以他们的姓名和电子邮箱及其他来分组:

return $students->groupBy(['skilllevel','teacher', 'name', 'email']);

这里是一些疯狂的嵌套结构,但他也有有可能的 :-)

{
    "professional": {
        "Peter": {
            "Mrs. Ella McClure": {
                "forest.bernier@example.com": [
                    {
                        "name": "Mrs. Ella McClure",
                        "email": "forest.bernier@example.com",
                        "skilllevel": "professional",
                        "teacher": "Peter"
                    }
                ]
            }
        },
        "Chris": {
            "Miss Assunta Predovic PhD": {
                "amari.klocko@example.com": [
                    {
                        "name": "Miss Assunta Predovic PhD",
                        "email": "amari.klocko@example.com",
                        "skilllevel": "professional",
                        "teacher": "Chris"
                    }
                ]
            }
        }
    },
    "intermediate": {
        "Markus": {
            "Keshawn Crona DVM": {
                "vkilback@example.org": [
                    {
                        "name": "Keshawn Crona DVM",
                        "email": "vkilback@example.org",
                        "skilllevel": "intermediate",
                        "teacher": "Markus"
                    }
                ]
            }
        }
    }
}

结论

我真的很喜欢现在用多个值来分组一个集合是如此简单。 语法简介而且效果很好。 对于这个新特性你要其他好的例子吗? 通过 Twitter 来告知我们。

BradStev 翻译于 2个月前

原文地址:https://christoph-rumpel.com/2018/01/gro...

译文地址:https://laravel-china.org/topics/8713/th...


本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

本帖已被设为精华帖!
回复数量: 3
暂无评论~~

  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!