Laravel - Group By 和 Key By 在一起

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38710694/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 14:13:51  来源:igfitidea点击:

Laravel - Group By & Key By together

mysqllaravelgroup-byeloquent

提问by dev7

Assuming I have the following MySQL tables to represent pricebooks, items and the relationship between them:

假设我有以下 MySQL 表来表示价格手册、项目以及它们之间的关系:

item - item_id|name|...etc
pricebook - pricebook_id|name|...etc

and the following pivot table

和以下 pivot table

pricebook_item - pricebook_id|item_id|price|...etc

I have the correlating Eloquent models: Pricebook, Itemand a repository named PricebookDatato retrieve the necessary information.

我有相关的 Eloquent 模型:PricebookItem以及一个命名PricebookData为检索必要信息的存储库。

Within the PricebookDatarepository, I need to get the pricebook data grouped by pricebook id and then keyed by item_id for easy access on client side.

PricebookData存储库中,我需要获取按 pricebook id 分组的 pricebook 数据,然后按 item_id 键入以便在客户端轻松访问。

If I do:

如果我做:

Pricebook::all()->groupBy('pricebook_id');

I get the information grouped by the pricebook_idbut inside each pricebook the keys are simple numeric index (it arrives as js array) and not the actual product_id. So when returning to client side Javascript, the result arrives as the following:

我得到了按 分组的信息,pricebook_id但在每个价格手册中,键是简单的数字索引(它作为 js 数组到达)而不是实际的 product_id。因此,当返回客户端 Javascript 时,结果如下:

pricebookData: {1: [{}, {}, {}...], 2: [{}, {}, {}...]}

The problem with the prices arriving as array, is that I can not access it easily without iterating the array. Ideally I would be able to receive it as:

价格作为数组到达的问题是,如果不迭代数组,我就无法轻松访问它。理想情况下,我可以将其接收为:

 pricebookData: {1: {1001:{}, 1002: {}, 1003: {}}, 2: {1001:{}, 1002: {}, 1003: {}}}
//where 1001, 1002, 1003 are actual item ids
//with this result format, I could simply do var price = pricebookData[1][1001]

I've also tried the following but without success:

我也尝试了以下但没有成功:

Pricebook::all()->keyBy('item_id')->groupBy('pricebook_id');

Pricebook::all()->keyBy('item_id')->groupBy('pricebook_id');

The equivalent of what I am trying to avoid is:

我试图避免的等价物是:

$prices = Pricebook::all();
$priceData = [];
foreach ($prices as $price) 
{
   if (!isset($priceData[$price->pricebook_id])) 
   {
      $priceData[$price->pricebook_id] = [];
   }
   $priceData[$price->pricebook_id][$price->item_id] = $price;
}
return $priceData;

I am trying to find a pure elegant Eloquent/Query Builder solution.

我试图找到一个纯粹优雅的 Eloquent/Query Builder 解决方案。

回答by alepeino

I think what you want is

我想你想要的是

Pricebook::all()
    ->groupBy('pricebook_id')
    ->map(function ($pb) { return $pb->keyBy('item_id'); });

You first group by Pricebook, then each Pricebook subset is keyed by item_id. You were on the right track with

您首先按 Pricebook 分组,然后每个 Pricebook 子集以 item_id 为键。你在正确的轨道上

Pricebook::all()->keyBy('item_id')->groupBy('pricebook_id');

unfortunately, as it is implemented, the groupByresets previous keys.

不幸的是,随着它的实施,groupBy重置以前的键。

Update:

更新:

Pricebook::all()->keyBy('item_id')->groupBy('pricebook_id', true);

(groupBysecond parameter $preserveKeys)

groupBy第二个参数$preserveKeys