Is there a way to group by elements in collection by model? - laravel

Is there a way to group by data in Laravel collection by model?
Example:
Illuminate\Support\Collection {#1743 ▼
#items: array:5 [▼
0 => App\Models\Inicijativa {#1789 ▶}
1 => App\Models\Obavestenje {#1742 ▶}
2 => App\Models\Obavestenje {#1733 ▶}
3 => App\Models\Samoprocena {#1672 ▶}
4 => App\Models\Samoprocena {#1795 ▶}
]
}
In this example i want to have 3 groups:
Inicijativa with 1 item
Obavestenje with 2 items
Samoprocena with 2 items
They don't have a column by which i can differentiate them.

Once you have a collection you can use whatever you want to group it:
$grouped = $collection->groupBy(function ($item) { return get_class($item); });
This will group the elements of the collection based on the result of applying get_class on each of them. This is allowed since the result of get_class is a string indicating the fully qualified name of the object's class

Related

Need to Get data of ID ( received in Array ) from database

Good Morning. I am trying to get the data for each BuffaloID which i get in array. From that ID i am trying to get milk record for each buffaloID. But 2nd query give the data for first id only. How can i get the data for each id.
Query
$buffalidforavgmilk = Buffalomilkrecord::groupBy('buffaloID')->get('buffaloID')
->pluck('buffaloID')->toArray();
array:4 [▼
0 => "Buffalo-01"
1 => "Buffalo-02"
2 => "Buffalo-03"
3 => "Buffalo-04"
]
When i try below query i received data only for first id
$avgbuffalomilk = Buffalomilkrecord::where('buffaloID',$buffalidforavgmilk)->
pluck('totalmilk')->toArray();
array:5 [▼
0 => "9.00"
1 => "13.00"
2 => "12.00"
3 => "13.00"
4 => "12.00"
]
I hope i describe my problem and where did i make mistake to get data for all ID
Thanks in Advance
use whereIn
$buffalidforavgmilk = ['1','2','3'];
$avgbuffalomilk = Buffalomilkrecord::whereIn('buffaloID',$buffalidforavgmilk)->pluck('totalmilk')->toArray();

Laravel Query with Sum of value from child table if value column in parent table greater than sum of value in child

I am trying to query for rows from transaction table where the amount is less than sum of allocations against that transaction row in allocations table. This works halfway. It is giving me all transaction queries with an additional field of "allocated_amount".
$all_transactions = Transaction::
withCount([
'allocations AS amount_allocated' => function ($query) {
$query->select(
DB::raw("CAST(SUM(amount) AS INTEGER)"
));
}
])
->where('contact_type','supplier')
->where('contact_id',$ehead->supplier_id)
->get()->toArray();
Result
0 => array:12 [▼
"id" => 4
"amount" => 10000
"created_by" => 1
"amount_allocated" => 7500
]
1 => array:12 [▼
"id" => 5
"amount" => 10000
"created_by" => 1
"amount_allocated" => 10000
]
But I don't want the second result to come up because amount = amount allocated. How to fix this query?
Tried using:
->where('amount','>','allocated_amount')
but maybe because it is additionally added filed, throws an error saying allocated field does not exist. I need it within the query, not as a separate addition.
Well, in this case you can simply use map()
$all_transactions = collect($all_transactions)->map(function ($row) {
if ($row['amount'] > $row['amount_allocated']) {
return $row;
}
})->filter()->toArray(); // filter() to remove null values

PHP array_map() always change my first index value to zero value

I have a controller in Laravel
This is my collection
$milestones = $this->getmilestones();
dump($milestones);
and the value is
array:3 [▼
0 => "["109"
1 => "110"
2 => "111"]"
]
And I tried this code based on the answer here.
So, I have code like this
array_unshift($milestones, $milestones[0]);
unset($milestones[0]);
dump($milestones);
and the value is (index was changed)
array:3 [▼
1 => "["109"
2 => "110"
3 => "111"]"
]
So, after unshifting the collections, I tried to use array_map to convert array of strings to array of integers.
$milestones = array_map('intval', $milestones);
dump($milestones);
But, I still got the same value. The first index returns 0 like this
array:3 [▼
1 => 0
2 => 110
3 => 111
]
What should I do?
Try this one
array_splice($milestone, 0, 1);
dump($milestone);
Ah, finally I got the results that I wanted. I try to remove square brackets and double quote. Because milestones is collection. So my code is
$milestones = str_replace(array('[', ']', '"'),'',$milestones);
Thank you all for your help
Use array_values this should re-index your array the way you need it:
$milestones = array_values($milestones);
If $milestones is a collection:
$milestones = $milestones->values();
The method values() will call array_values on your items defined in your collection instance.
Source: http://php.net/manual/en/function.array-values.php

Group the result of an already grouped query sql/laravel

Hello everyone this is my first post and after giving this a lot of work my head just doesn't want to cooperate anymore, I've searched online for answers but can't find related cases, I am working in laravel 5.2 with a query, said query is to get the progress on items and count the items that share the same progress to display in a pie chart.
Relations are as follows:
I have 3 tables:
Items
Steps to complete (each one has a percentage).
Progress of each item per step (Completed true or false)
Right now I have this code
table('items as i')
->join('items_sectors as is', 'i.sector_id', '=', 'is.id')
->join('sectors_steps_progress as stp', 'i.id', '=', 'stp.item_id')
->join('sectors_steps as cs', 'stp.step_id', '=', 'cs.id')
->where('stp.completed', true)
->selectRaw('count(distinct i.id) as count, CONCAT(sum(cs.percentage), "%") as percentage')
->groupBy('stp.completed', 'i.id');
And this with some testing data outputs
array:3 [▼
0 => {#2042 ▼
+"count": 1
+"percentage": "50%"
}
1 => {#2043 ▼
+"count": 1
+"percentage": "100%"
}
2 => {#2044 ▼
+"count": 1
+"percentage": "100%"
}
]
What I want is to now join all the matchings "percentage" and count them so it would end up like:
array:3 [▼
0 => {#2042 ▼
+"count": 1
+"label": "50%"
}
1 => {#2043 ▼
+"count": 2
+"label": "100%"
}
]
Thanks a lot if anyone can help me with this, I'm still trying to figure it out :(
if result is not a collection convert it to a collection and apply the code below
$result = $array->groupBy("percentage")
->map(function($q){
$newArray['count'] = count($q);
$newArray['percentage'] = $q[0]['percentage'];
return $newArray;
})->values();
return $result;
Hope it helps.

get the first, the second, the third element of collection

I have a collection like that:
Collection {#750 ▼
#items: array:18 [▼
18 => User {#691 ▶}
19 => User {#696 ▶}
20 => User {#701 ▶}
]
}
Where 18, 19, 20 should vary
I tried to call with
$collection->get(0);
$collection->get(1);
$collection->get(2);
But obviously, it doesn't work
I found a workaround with shift, that return first element and remove it from the collection,
$el1 = $collection->shift();
$el2 = $collection->shift();
$el3 = $collection->shift();
But in this case, my original collection is destroyed.
Any idea how I should do it?
You can use slice() method:
$collection->slice(0, 3)
The slice method returns a slice of the collection starting at the given index. If you would like to limit the size of the returned slice, pass the desired size as the second argument.
You can use values() as:
$collection = $collection->values();
then you can use it as:
$collection->get(0);
$collection->get(1);
$collection->get(2);
You can either loop over them:
foreach ($collection as $element) {
// use $element
}
Or you can reset the keys to be sequentially indexed:
$collection = $collection->values();
$element1 = $collection->get(0);
$element2 = $collection->get(1);
$element3 = $collection->get(2);
There are many ways you can access thoes values. For example, you can get keys by calling:
$keys = $collection->keys()
Then call by the ordered keys you wanted:
if (isset($keys[0])) $collection->get($keys[0]);

Resources