How to count and group a query by two columns? - php

I have an collection returned by a Eloquent Query. Each element of the collection is an array with only two integers elements (branch_id, event_id). I need to make and array or collection where all the identical pairs of elements are combined in the same array, because I need to count how many times a pair of elements appears and also being able to access to its values.
I am using the groupBy method of Query Builder to group the result by two columns, but it only returns the data combined by the first column name I passed to the method.
For Example:
array:15 [▼
0 => {#277 ▼
+"branch_id": 1
+"event_id": 1
}
1 => {#279 ▼
+"branch_id": 1
+"event_id": 1
}
2 => {#280 ▼
+"branch_id": 1
+"event_id": 1
}
3 => {#281 ▼
+"branch_id": 1
+"event_id": 1
}
4 => {#282 ▼
+"branch_id": 1
+"event_id": 2
}
5 => {#283 ▼
+"branch_id": 1
+"event_id": 21
}
6 => {#292 ▼
+"branch_id": 58
+"event_id": 21
}
7 => {#284 ▼
+"branch_id": 2
+"event_id": 5
}
8 => {#285 ▼
+"branch_id": 3
+"event_id": 3
}
9 => {#286 ▼
+"branch_id": 4
+"event_id": 4
}
10 => {#287 ▼
+"branch_id": 5
+"event_id": 9
}
11 => {#289 ▼
+"branch_id": 5
+"event_id": 9
}
12 => {#288 ▼
+"branch_id": 5
+"event_id": 8
}
13 => {#290 ▼
+"branch_id": 7
+"event_id": 10
As you can see, the first four arrays has the same values (branch_id: 1, event_id: id) I need to retrieve those values combined in a single array, and so forth with every array that has the same values.

I was able to do it this way...
public function getAllIncidents()
{
$i = 0;
$data = [];
$values = DB::table('incidents')->select('branch_id', 'event_id')->orderBy('branch_id')->get()->groupBy('event_id');
foreach ($values as $key => $value) {
$collections[$i] = $value->groupBy('branch_id');
$i++;
}
$collections = array_collapse($collections);
$i = 0;
foreach ($collections as $key => $collection) {
$array = $collection->toArray();
$data[$i]['count'] = sizeof($array);
$data[$i]['branch_id'] = $array[0]->branch_id;
$data[$i]['event_id'] = $array[0]->event_id;
$i++;
}
return response()->json($data, 200);
}

Related

How to combine the output from an object and an array?

I have a db query that returns a value to the $result variable that looks like this:
Collection {#710 ▼
#items: array:16 [▼
0 => {#717 ▼
+"utest_step_id": 18
+"value": "1"
+"count": 26
}
1 => {#716 ▼
+"utest_step_id": 18
+"value": "2"
+"count": 23
}
2 => {#709 ▶}
3 => {#711 ▶}
4 => {#713 ▶}
5 => {#714 ▶}
6 => {#715 ▶}
7 => {#718 ▶}
8 => {#719 ▶}
9 => {#720 ▶}
10 => {#721 ▶}
11 => {#722 ▶}
12 => {#723 ▶}
13 => {#724 ▶}
14 => {#725 ▶}
15 => {#726 ▶}
]
}
I have an array called $steps that I need to combine with the data that looks like this:
[▼
0 => {#676 ▼
+"id": 18
+"step": 1
+"type": "select many image"
+"featured": false
+"data": {#664 ▼
+"description": "Ut quaerat ut sed molestiae."
+"randomize": 0
+"options": array:4 [▼
0 => {#671 ▼
+"position": 1
+"image_url": "http://lorempixel.com/455/255/?67678"
+"caption": "Prof."
+"image_source": "http://lorempixel.com/455/255/?67678"
}
1 => {#668 ▼
+"position": 2
+"image_url": "http://lorempixel.com/455/255/?23876"
+"caption": "Ms."
+"image_source": "http://lorempixel.com/455/255/?23876"
}
2 => {#670 ▼
+"position": 3
+"image_url": "http://lorempixel.com/455/255/?45833"
+"caption": "Prof."
+"image_source": "http://lorempixel.com/455/255/?45833"
}
3 => {#677 ▼
+"position": 4
+"image_url": "http://lorempixel.com/455/255/?83800"
+"caption": "Dr."
+"image_source": "http://lorempixel.com/455/255/?83800"
}
]
}
}
1 => {#690 ▶}
2 => {#697 ▶}
3 => {#704 ▶}
4 => {#706 ▶}
]
I am trying to insert the value from count in $results into the $steps->data->options array.
Here is my code:
foreach ($results as $result) {
$comparison_field = 'position';
for ($i=0; $i < sizeof($steps); $i++) {
if ($result->utest_step_id == $steps[$i]->id) {
foreach ($steps[$i]->data->options as $option) {
$option->count = 0;
$option->count = $result->count;
}
}
}
}
The problem is I am ending up with the count from the last $result->utest_step_id in each count item in the $option.
Where am I going wrong?
You have a for loop iterating over all of the elements in $steps for each entry in $results. This results in everything in $steps being overwritten for each element in $results. If these arrays are supposed to line up, grab an $id from the $results loop:
foreach ($results AS $id=>$result)
and use that instead of $i in a for loop.

PHP Get a specific property from an array of objects with different array count

I am in a confusing situation right now.
So, I have an array of objects
array:3 [▼
0 => array:5 [▶]
1 => array:2 [▶]
2 => array:10 [▶]
]
Each array items contains another array which will have objects
array:3 [▼
0 => array:5 [▼
0 => {#215 ▼
+"DefaultTimeLength": 40
+"ProgramID": 4
+"NumDeducted": 1
+"ID": 245
+"Name": "30-Swedish-Massage"
}
1 => {#216 ▼
+"DefaultTimeLength": 70
+"ProgramID": 4
+"NumDeducted": 1
+"ID": 246
+"Name": "60-Swedish-Massage"
}
2 => {#217 ▶}
3 => {#218 ▶}
4 => {#219 ▶}
]
1 => array:2 [▶]
2 => array:10 [▶]
]
What I want to achieve is, I want to get the 'ID' and 'Name' as an array for every array of objects from this array. Since, every array inside the main array have different counts, I cannot use a FOR loop, to get the required data.
Any ideas?
use nested foreach loop e.g:
foreach($main as $m){
foreach($m as $item){
echo $item->ID ." ".$item->Name;
}
}
use 2 foreach loop inside eachother
foreach ($array as $item) {
foreach ($item as $sub) {
echo $sub['ID'] . " " . $sub['Name'] . "<br>";
}
}
your full code will be something like this

Laravel collection by month

I've got a collection and I need the total users by month.
So I've done this:
array_replace(array_fill_keys(range(0, 11), 0), $users->groupBy('created_at.month')->toArray())
It's sort of working because I get this:
array:12 [▼
0 => 0
1 => 0
2 => 0
3 => 0
4 => 0
5 => 0
6 => array:1 [▶]
7 => array:2 [▶]
8 => 0
9 => 0
10 => 0
11 => 0
]
The problem I face now is that I don't need the 2 arrays at position 6 and 7 but I need the counts.
So I was thinking of something like:
$users->groupBy('created_at.month')->count()->toArray();
But, that's obviously not working. Any ideas ?
try using map method
$collection->map(function ($item, $key) {
return count($item);
});

Merge 2 arrays by their index in each row [duplicate]

This question already has answers here:
PHP's array_merge_recursive behaviour on integer keys
(5 answers)
Closed 5 months ago.
I have 2 arrays, each will always have the same number of rows and same number of values per row.
I need to merge the 2 arrays together, to combine the results on each row, but in a particular way (there will always be only 3 results per row on each array too):
For example, for each row, take the first result of each array, and put them next to each other, then the second result of each array, and put them next to each other, then finally the third.
So Array 1's value will always precede Array 2's value (example shown below):
Array 1:
array:7 [▼
24 => array:3 [▼
0 => 0
1 => 0.66666666666667
2 => 0.66666666666667
]
25 => array:3 [▶]
26 => array:3 [▶]
27 => array:3 [▶]
29 => array:3 [▶]
30 => array:3 [▶]
31 => array:3 [▶]
]
Array 2:
array:7 [▼
24 => array:3 [▼
0 => 0.375
1 => 0.42857142857143
2 => 0.55555555555556
]
25 => array:3 [▶]
26 => array:3 [▶]
27 => array:3 [▶]
29 => array:3 [▶]
30 => array:3 [▶]
31 => array:3 [▶]
]
Intended Combined Array Format:
array:7 [▼
24 => array:6 [▼
0 => 0
1 => 0.375
2 => 0.66666666666667
3 => 0.42857142857143
4 => 0.66666666666667
5 => 0.55555555555556
]
25 => array:6 [▶] ...
Current loop which returns the incorrect layout:
$results = array();
foreach ($questionDetails as $key => $question) {
for ($i = 0; $i < 3; $i++) {
$results[$key][] = $array1[$key] + $array2[$key];
}
}
Returns:
array:7 [▼
24 => array:3 [▼
0 => array:3 [▼
0 => 0
1 => 0.66666666666667
2 => 0.66666666666667
]
1 => array:3 [▼
0 => 0
1 => 0.66666666666667
2 => 0.66666666666667
]
2 => array:3 [▼
0 => 0
1 => 0.66666666666667
2 => 0.66666666666667
]
]
25 => array:3 [▶]
26 => array:3 [▶]
27 => array:3 [▶]
29 => array:3 [▶]
30 => array:3 [▶]
31 => array:3 [▶]
]
I'm unsure why my loop isn't just adding the three values from each row together - but then I think they still won't be in the right order, but I'm unsure of how to approach this.
Many thanks.
This is the "unfancy" (but save) solution if I understand your question correctly - all keys are preserved an set as desired:
$array1;
$array2;
$results = array();
foreach ($questionDetails as $key => $question1) {
$question2 = $array2[$key];
$tp = array();
$tp[0] = $question1[0];
$tp[1] = $question2[0];
$tp[2] = $question1[1];
$tp[3] = $question2[1];
$tp[4] = $question1[2];
$tp[5] = $question2[2];
$results[$key] = $tp;
}
EDIT: There is a way more flexible way to implement this where the number of arguments may vary (see PHP: array_merge() in alternate order (zip order)?).
$array1;
$array2;
function array_zip(...$arrays) {
return array_merge(...array_map(null, ...$arrays));
}
$results = array();
foreach ($questionDetails as $key => $question1) {
$results[$key] = array_zip($question1,$array2[$key]);
}
I would do this:
$combined = array();
foreach($array1 as $key => $value){
$combined[$key] = array();
foreach($value as $key2 => $value2){
$combined[$key][] = $value2;
$combined[$key][] = $array2[$key][$key2];
}
}
For a variable number of records.

Create dynamic table with multi dimensional array data?

Hello experts I am new in laravel and php. I have an multi dimensional array and with this array data I want to create a dynamic table and its maximum count will be 10 as a newbie I can't reach to the perfect result. My array as bellow:
array:4 [▼ 0 => array:2 [▼
0 => {#404 ▼
+"id": 290
+"amount": "8500.00"
}
1 => {#403 ▼
+"id": 399
+"amount": "8500.00"
} ] 1 => array:4 [▼
0 => {#402 ▼
+"id": 107
+"amount": "6590.00"
}
1 => {#401 ▼
+"id": 355
+"amount": "6590.00"
}
2 => {#400 ▼
+"id": 698
+"amount": "6590.00"
}
3 => {#399 ▼
+"id": 734
+"amount": "6590.00"
} ] 2 => array:1 [▼
0 => {#108 ▼
+"id": 21
+"amount": "3240.00"
} ] 3 => array:2 [▼
0 => {#397 ▼
+"id": 27
+"amount": "3030.00"
}
1 => {#396 ▼
+"id": 50
+"amount": "3030.00"
} ] ]
And With this array I want to create a table like as bellow:
Serial ID
Amount 1 290
8500 1 399
8500
2 107
6590 2 355
6590 2 698
6590 2 734
6590
3 108
3240
4 27 3030
4 50 3030
And I am trying with this in laravel :
$flag = 0;
$tableDesign = '';
for($i=0;$i<count($data);$i++) {
$tableDesign .="<tr><td>".$flag++."</td><td>".$data[$i][0]."</td> <td>".$data[$i][1]."</td></tr>";
if($flag == 10)
{ return;}
}
Thanks in advance.
You can rearrange your array before displaying in the table like this:
$newData = array();
$flag = 1;
foreach($data as $key => $elements) {
if($flag > 10) {
break;
}
foreach($elements as $element) {
$newDataElement = array(
'serial' => $key + 1,
'id' => $element['id'],
'amount' => $element['amount']
);
array_push($newData, $newDataElement);
}
$flag++;
}
Then you can display it simply:
<?php foreach($newData as $element): ?>
<tr>
<td><?php print $element['serial']?></td>
<td><?php print $element['id']?></td>
<td><?php print $element['amount']?></td>
</tr>
<?php endforeach; ?>

Categories