问题描述
在Laravel中,如果我执行查询:
In Laravel, if I perform a query:
$foods = Food::where(...)->get();
...然后$foods
是 Illuminate集合在Food
个模型对象中. (本质上是一系列模型.)
...then $foods
is an Illuminate Collection of Food
model objects. (Essentially an array of models.)
但是,此数组的键很简单:
However, the keys of this array are simply:
[0, 1, 2, 3, ...]
...因此,如果要更改Food
为24的Food
对象,我将无法执行此操作:
...so if I want to alter, say, the Food
object with an id
of 24, I can't do this:
$desired_object = $foods->get(24);
$desired_object->color = 'Green';
$desired_object->save();
...因为这只会更改数组中的第25个元素,而不会更改id
为24的元素.
...because this will merely alter the 25th element in the array, not the element with an id
of 24.
如何通过ANY属性/列(例如但不限于id/颜色/age等)从集合中获取单个(或多个)元素?
我当然可以做到:
foreach ($foods as $food) {
if ($food->id == 24) {
$desired_object = $food;
break;
}
}
$desired_object->color = 'Green';
$desired_object->save();
...但是,那只是毛病.
...but, that's just gross.
当然,我可以这样做:
$desired_object = Food::find(24);
$desired_object->color = 'Green';
$desired_object->save();
...但是那是总的来说,因为当我已经在$foods
集合中有了所需的对象时,它会执行其他不必要的查询.
...but that's even more gross, because it performs an additional unnecessary query when I already have the desired object in the $foods
collection.
提前感谢您的指导.
为清楚起见,您可以 调用Illuminate Collection上的->find()
而不会产生其他查询,但是 only 接受主ID.例如:
To be clear, you can call ->find()
on an Illuminate Collection without spawning another query, but it only accepts a primary ID. For instance:
$foods = Food::all();
$desired_food = $foods->find(21); // Grab the food with an ID of 21
但是,仍然没有干净的(非循环,非查询)方式来从Collection的属性中获取元素,如下所示:
However, there is still no clean (non-looping, non-querying) way to grab an element(s) by an attribute from a Collection, like this:
$foods = Food::all();
$green_foods = $foods->where('color', 'green'); // This won't work. :(
推荐答案
您可以使用 filter
,就像这样:
You can use filter
, like so:
$desired_object = $food->filter(function($item) {
return $item->id == 24;
})->first();
filter
也会返回一个Collection
,但是由于您知道只有一个,因此可以在该Collection
上调用first
.
filter
will also return a Collection
, but since you know there will be only one, you can call first
on that Collection
.
您不再需要过滤器了(或者也许曾经,我不知道它已经快4年了).您可以只使用 first
:
You don't need the filter anymore (or maybe ever, I don't know this is almost 4 years old). You can just use first
:
$desired_object = $food->first(function($item) {
return $item->id == 24;
});
这篇关于Laravel:通过属性从集合中获取对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!