如何使用Laravel eloquent/collections计算PHP中类似键的总数
我目前有API返回的以下json响应。我能用拉威尔的口才把它还给你。有几个用户,每个用户都有几个收据。收据具有类型和状态。我想尝试获取与类型和状态相关的每个收据的总金额。我能够使用如何使用Laravel eloquent/collections计算PHP中类似键的总数,php,laravel,laravel-5,eloquent,Php,Laravel,Laravel 5,Eloquent,我目前有API返回的以下json响应。我能用拉威尔的口才把它还给你。有几个用户,每个用户都有几个收据。收据具有类型和状态。我想尝试获取与类型和状态相关的每个收据的总金额。我能够使用 $this->user->with('receipts')->has('receipts')->get(['id', 'name']); 我尝试过使用多种laravel collections方法 但我仍然无法得到想要的回应 { "id": 1, "n
$this->user->with('receipts')->has('receipts')->get(['id', 'name']);
我尝试过使用多种laravel collections方法
但我仍然无法得到想要的回应
{
"id": 1,
"name": "kent",
"receipts": [
{
"id": 1,
"user_id": 1,
"type_id": 1,
"status": 0,
"amount": 100
},
{
"id": 2,
"user_id": 1,
"type_id": 1,
"status": 0,
"amount": 100
},
{
"id": 3,
"user_id": 1,
"type_id": 2,
"status": 1,
"amount": 50
},
{
"id": 4,
"user_id": 1,
"type_id": 2,
"status": 0,
"amount": 30
},
{
"id": 5,
"user_id": 1,
"type_id": 2,
"status": 0,
"amount": 30
},
{
"id": 6,
"user_id": 1,
"type_id": 1,
"status": 0,
"amount": 20
},
{
"id": 7,
"user_id": 1,
"type_id": 1,
"status": 1,
"amount": 10
}
]
},
{
"id": 2,
"name": "allison",
"receipts": [
{
"id": 9,
"user_id": 2,
"type_id": 1,
"status": 0,
"amount": 20
}
]
}
]
我希望得到下面的答案
{
"id": 1,
"name": "kent",
"receipts": [
{
"performance and deleted": 220,
"performance and not deleted": 10,
"project and deleted": 60,
"project and deleted": 50
}
]
},
{
"id": 2,
"name": "allison",
"receipts": [
{
"performance and deleted": 20,
"performance and not deleted": 0,
"project and deleted": 0,
"project and not deleted": 0
}
]
}
]
您可以使用foreach和其他循环来生成所需的json! 使用此函数将集合转换为所需的json:
public function convert(Collection $collection)
{
$result_collection = $collection;
$payment_collections = [];
foreach ($result_collection->receipts as $receipt)
{
$payment["type_id${receipt->type_id} and status${$receipt->status}"] = $receipt->amount;
}
$result_collection->receipts = $payment_collections;
return $result_collection;
}
这和计算总量的方法是一样的。只需放置一个foreach并将每个金额添加到一个初始化为0的变量中
还有其他方法,如在资源集合中更改数组函数您应该能够使用
$this->user->with(['receipts' => function($query) {
$query->selectRaw("SUM(amount) as amount, type_id, status, user_id")->groupBy('type_id', 'status', 'user_id');
}])->has('receipts')->get(['id', 'name']);
您可以使用收集方法来获得所需的输出
$this->user->with(['receipts' => function($query) {
$query->selectRaw("SUM(amount) as amount, type_id, status, user_id")->groupBy('type_id', 'status', 'user_id');
}])->has('receipts')->get(['id', 'name'])
->each(function ($user) {
$user->setRelation(
'receipts',
$user->receipts->mapWithKeys(function ($receipt) {
return [
$receipt->type_id . ' and ' . $receipt->status => $receipt->amount // format the key as you wish
];
})
);
})
我编写的脚本假设您的数据是PHP数组,因此您可以更改我代码的某些部分。 例如,您可以更改:
$row['receipts']
// To
$row->receipts
反正
// The function in your controller
function index(){
$users=User::whereHas('receipts')->with('receipts')->get()->toArray();
return convert($users);
}
// The helper function
function convert($data){
$data=collect($data);
$allTypes=[];
$allStatuses=[];
return $data->each(function($row) use (&$allTypes,&$allStatuses){
$types=collect($row['receipts'])->pluck('type_id')->toArray();
$statuses=collect($row['receipts'])->pluck('status')->toArray();
$allTypes=array_unique(array_merge($allTypes,$types));
$allStatuses=array_unique(array_merge($allStatuses,$statuses));
})->map(function ($row,$index) use (&$allTypes,&$allStatuses){
$result=[];
$receipts=collect($row['receipts']);
foreach ($allTypes as $type){
foreach ($allStatuses as $status){
$result["type_id {$type} and status {$status}: "]=$receipts->where('type_id',$type)->where('status',$status)->sum('amount');
}
}
$row['receipts']=$result;
return $row;
});
}
我正在获取的属性[receipts]在此集合实例上不存在。我尝试了它,但是,这就是我正在获取的,一个空的收据数组
[{“id”:1,“name”:“kent”,“receipts”:[]},{“id”:2,“name”:“allison”,“receipts”:[]}]
@CEJ查看更新的答案。还需要将外键添加到select语句中。如何才能像预期的答案一样填充它?这会对类型和状态进行分组您的意思是您需要像type\u id1和status0这样的键是的我需要像admin status:220这样的键用户状态:10
超级管理员状态“:60
阅读我写的内容您可能会更改部分代码,我测试了它,效果很好,我上传了结果器的屏幕截图,如果您不想更改我的代码,可以使用->get()->toArray()将DB结果解析为数组;然后将其传递给我编写的函数。我编辑了代码,并向您展示了如何获取用户,首先再次检查它感谢编辑。有没有办法只使用收集方法而不使用foreach循环。请检查更新后的预期答案。这就是我所期望的