我正在寻找一个集合并返回包含集合中两个字段的平面数组。我想要的是什么:
$collection = new Collection([
[
"a"=>"a1",
"b"=>"b1",
"c"=>"c1"
],
[
"a"=>"a2",
"b"=>"b2",
"c"=>"c2"
],
[
"a"=>"a3",
"b"=>"b3",
"c"=>"c3"
]
]);
//desired output:
[
["a1","b1"],
["a2","b2"],
["a3","b3"]
];
我会认为这是一个功能,但它不是:
$collection->lists(["a","b"]);
我目前的解决方案看起来效率不高,因为它们可能有数千行:
$collection->lists("a")->zip($collection->lists("b"));
我是否缺少某项功能?感谢。
编辑:我也使用了这样的地图:
$collection->map(function($row)){
return [$row['a'],$row['b']];
}
这似乎比我想要的更加习惯。如果没有本地方式,我最终可能会使用此函数为Collection编写包装器。
答案 0 :(得分:9)
如果您想专门使用集合,可以扩展当前集合API,因为它是可宏的,执行如下操作:
Collection::macro('pluckMultiple', function ($assoc) {
return $this->map(function ($item) use ($assoc) {
$list = [];
foreach ($assoc as $key) {
$list[$key] = data_get($item, $key);
}
return $list;
}, new static);
});
在上面的示例中,我将键作为返回的一部分包含在内,但可以删除它。
$collection->pluckMultiple(['a', 'b']);
会给你你想要的东西。
如果您想从Eloquent集合中提取项目,上述方法可以很好地工作,例如:
$books = Book::with('author')->get();
$books->pluckMultiple(['title', 'author.name', 'author.surname']);
答案 1 :(得分:5)
您可以使用
$plucked = $collection->pluck('b','a');
$plucked->all();
这将给出以下结果
Collection {#651 ▼
#items: array:3 [▼
"a1" => "b1"
"a2" => "b2"
"a3" => "b3"
]}
并使用此代码获取给定格式
foreach ($plucked as $key => $item)
{
$temp[] = [ $key, $item];
}
这将产生以下结果。
array:3 [▼
0 => array:2 [▼
0 => "a1"
1 => "b1"
]
1 => array:2 [▼
0 => "a2"
1 => "b2"
]
2 => array:2 [▼
0 => "a3"
1 => "b3"
]
]
答案 2 :(得分:0)
如果您使用Laravel 5.0,您会发现Illuminate\Laravel\Collection
不接受宏,因此Leon的优雅解决方案无效。如果(像我一样)你无法升级到更新的Laravel版本,你可以使用此功能作为解决方法:
<?php
use Illuminate\Support\Collection;
/**
* List values from collection. Unlike $collection->lists('key'), this function allows using multiple keys.
*
* In newer Laravel versions things like that can be done with collection macros, but not in 5.0.
*
* @param Collection $collection
* @param array|string $properties
* @param string $id
* @return array
*/
function lists(Collection $collection, $properties, $id = null) {
$result = [];
$i = 0;
foreach ($collection as $item) {
$k = $id ? $item->$id : $i;
if (is_array($properties)) {
$result[$k] = [];
foreach ($properties as $property) {
$result[$k][$property] = $item->$property;
}
}
else {
$result[$k] = $item->$properties;
}
$i++;
}
return $result;
}
然后你就像这样使用它:
$users = User::all();
$someData = lists($collection, ['name', 'email']);
// Or, if you want to key by id:
$someData = lists($collection, ['name', 'email'], 'id');
至于你把这个功能放在哪里 - 我把这样的东西放在app / Support / helpers.php中,然后像这样更新我的composer.json:
"autoload": {
...
"files": [
"app/Support/helpers.php"
]
},
然后运行composer dump
答案 3 :(得分:-1)
我修改了Leon Vismer的答案,在数组中使用点符号。
Collection::macro('pluckMultiple', function ($assoc) {
/* @var $this Collection */
return $this->map(function ($item) use ($assoc) {
$list = [];
foreach ($assoc as $keys) {
$old_key = $keys;
$keys = explode('.', $keys);
$ref = &$list;
while (count($keys) > 1) {
$key = array_shift($keys);
if (!isset($ref[ $key ]) || !is_array($ref[ $key ])) {
$ref[ $key ] = [];
}
$ref = &$list[ $key ];
}
$ref[ array_shift($keys) ] = data_get($item, $old_key);
}
return $list;
}, new static);
});