我在使用 Laravel Collection 类时遇到一些问题。
我正在尝试做的事情:
- 我有一个多站点解决方案,其中一个站点有“促进者”。有时一位协调员会出现在多个网站上,而不仅仅是一个。
- 我想在主页上列出所有协调员和他们所在的网站,但我不想要多个用户。
所以我目前做的是:
- 找到协调员。
- 使用 Collection 收集协助者并使用
unique('name')
。
这为我提供了独特的辅助器,但只选择它检测到的第一个辅助器,然后删除其他辅助器。
假设我有这个收藏:
Collection {
#items: array:3 [
0 => array:2 [
"name" => "John"
"site" => "Example"
]
1 => array:2 [
"name" => "Martin"
"site" => "Another"
]
2 => array:2 [
"name" => "John"
"site" => "Another"
]
]
}
使用 unique()
我会得到:
Collection {
#items: array:3 [
0 => array:2 [
"name" => "John"
"site" => "Example"
]
1 => array:2 [
"name" => "Martin"
"site" => "Another"
]
]
}
这就是我想要得到的:
Collection {
#items: array:3 [
0 => array:2 [
"name" => "John"
"site" => ["Example", "Another"]
]
1 => array:2 [
"name" => "Martin"
"site" => "Another"
]
]
}
有谁知道我如何使用 Laravel 的集合类来实现这一点?
最佳答案
当遇到收藏问题时,请记住 reduce是您武器库中的强大工具。
基于我无法开始工作的 Sam 的回答,我认为将 reduce 与 groupBy 一起使用应该可行......
$sites = collect([
["name" => "John", "site" => "Example"],
["name" => "Martin", "site" => "Another"],
["name" => "John", "site" => "Another"],
]);
$sites->groupBy('name')->reduce(function ($result, $item) {
$result[] = [
'name' => $item->first()['name'],
'sites' => $item->pluck('site')->toArray()
];
return $result;
}, collect([]))->toArray();
然后从控制台...
λ php artisan tinker
Psy Shell v0.8.2 (PHP 7.0.10 ÔÇö cli) by Justin Hileman
>>> $sites = collect([
... ["name" => "John", "site" => "Example"],
... ["name" => "Martin", "site" => "Another"],
... ["name" => "John", "site" => "Another"],
... ]);
=> Illuminate\Support\Collection {#698
all: [
[
"name" => "John",
"site" => "Example",
],
[
"name" => "Martin",
"site" => "Another",
],
[
"name" => "John",
"site" => "Another",
],
],
}
>>> $sites->groupBy('name')->reduce(function ($result, $item) {
... $result[] = ['name' => $item->first()['name'], 'sites' => $item->pluck('site')->toArray()];
...
... return $result;
... }, collect([]))->toArray();
=> [
[
"name" => "John",
"sites" => [
"Example",
"Another",
],
],
[
"name" => "Martin",
"sites" => [
"Another",
],
],
]
需要注意的一件事是,您在问题中指定,如果只有一个站点,则站点应返回单个字符串,如果有多个站点,则应返回一个数组。上述解决方案不提供此功能!我认为这是不一致的,您应该始终为 sites 键返回一个数组,即使它只有一个值也是如此,因为这会使以后阅读和操作变得更加困难。
但是,如果这很重要,您可以在使用 pluck 设置数组时检查是否有很多站点,如果没有,您可以将其设置为单个字符串,如下所示:
$sites->groupBy('name')->reduce(function ($result, $item) {
$result[] = [
'name' => $item->first()['name'],
'sites' => $item->pluck('site')->count() > 1 ? $item->pluck('site') : $item->first()['site']
];
return $result;
}, collect([]))->toArray();
这会产生...
[
[
"name" => "John",
"sites" => [
"Example",
"Another",
],
],
[
"name" => "Martin",
"sites" => "Another",
],
]
关于php - 复杂的 Laravel 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42804242/