Laravel Where Collection - arrays

I am having troubles with laravel collections. This is my script:
foreach($getResult->all()['results'] as $key => $val) {
$colVal = collect($val);
$dataDiff = [];
$getWithoutLine = $colVal->except(['line_items']);
$getDiff = $colVal->only(['line_items']);
foreach($colVal->all()['line_items'] as $val1) {
if ((int)$val1['quantity'] - (int)$val1['deliveries']['quantity'] > 0) {
$getWithoutLine['status'] = 'partially_received';
$dataDiff[] = $val1;
}
}
$getWithoutLine['line_items'] = $dataDiff;
//dd($getWithoutLine);
$filtered = $getWithoutLine->whereStrict('status', 'submitted');
//dd($filtered->all());
$getFullCol[] = $filtered;
}
When dd($getWithoutLine) is executed, then collection appears like this:
Collection {#464
#items: array:24 [
"id" => "13c023aa-b471-4276-a0fc-a22d3677be91"
"status" => "submitted"
"date" => "2018-09-19"
"time" => "11:54:22"
"number" => "PO000003"
"description" => "Pesanan Pembelian, Vendor 1"
"supplier" => array:4 [
"id" => null
"code" => null
"name" => null
"classification" => null
]
"term_of_payment" => array:6 [
"due_date" => null
"due_days" => 0
"late_charge_rate" => 0.0
"discount_date" => null
"discount_days" => 0
"early_discount_rate" => 0.0
]
...
...
]
}
But when dd($filtered->all()) is executed then the result is empty. Why is that?
I can't understand what I am doing wrong.
=======
EDITED
When I change dd($filtered->all()) to dd($filtered) the result is actually same :
Collection {#463
#items: []
}
======
EDITED
When I Change $filtered = $getWithoutLine->whereStrict('status', 'submitted'); to $getWithoutLine->only('status'); the collection is work...
Collection {#468
#items: array:1 [
"status" => "submitted"
]
}

Related

How to order an array by bool values in laravel livewire

I have an array, I want to order that array by "is_available" key, (true first)
I'm using laravel 8 and a livewire component
0 => array:12 [▼
"id" => 1
"name" => "치킨 ~The Chicken~"
"is_available" => true
"nearest_customer_distance" => 4905.4423678942
"customers" => array:26 [▶]
]
1 => array:12 [▼
"id" => 2
"name" => "混ぜるな危険"
"is_available" => false
"customers" => array:10 [▶]
]
2 => array:12 [▼
"id" => 3
"name" => "Oh! Bánh mì"
"is_available" => true
"customers" => array:8 [▶]
]
3 => array:12 [▼
"id" => 5
"name" => "CHIJIMI DEVIL"
"is_available" => false
"customers" => array:44 [▶]
]
]
I'm trying this
$newFranchiseList = $this->getFranchiseListActualPage();
$finalFranchiseList = array_merge($this->franchiseList, $newFranchiseList);
$finalFranchiseList = collect($finalFranchiseList)->sortBy('is_available')->reverse();
$this->franchiseList = $finalFranchiseList->toArray();
but I get the order by ID in my view, this is my view
#forelse($franchiseList as $franchise)
#if($franchise['is_available'])
{{$franchise['name']}}
IS AVAILABLE
#else
{{$franchise['name']}}
NOT AVAILABLE
#endif
#empty
#endforelse
if I do a dump($this->franchiseList) the list is shown with the order of is_available!
note: $this->franchiseList is never used in the component, the only line to be used is the last one, if I don't use this line, the list is empty
component data collection process
first, in javascript call a livewire listener
window.livewire.emit('franchises:selectedCoords', JSON.stringify(selectedCoords));
then that is received by the component
public $selectedLatitude,
$selectedLongitude,
$perPage = 20,
$franchiseList = [],
$page = 1,
$totalFranchises = 0,
$isLoaded = false;
protected $listeners = [
'franchises:selectedCoords' => 'getCoords'
];
public function render()
{
return view('livewire.franchise-list');
}
public function getCoords($selectedCoords)
{
if ($selectedCoords) {
if (!empty($this->franchiseList)) {
$this->clearList();
}
$this->selectedLatitude = json_decode($selectedCoords, true)['lat'];
$this->selectedLongitude = json_decode($selectedCoords, true)['lng'];
}
$this->getFranchiseList();
}
public function getFranchiseList()
{
if ($this->selectedLatitude && $this->selectedLongitude) {
if (!$this->allFranchisesAreLoaded())
{
$newFranchiseList = $this->getFranchiseListActualPage();
$finalFranchiseList = array_merge($this->franchiseList, $newFranchiseList);
$this->franchiseList = collect($finalFranchiseList)->sortBy('is_available')->reverse()->toArray();
}
$this->isLoaded = true;
}
}
remember that $this->franchiseList is never overwritten, that is, it is only used once, in the line $this->franchiseList = collect($finalFranchiseList)->sortBy('is_available')->reverse()->toArray (); and if it is not done, it ends up being an empty array, so there is no other $this->franchiseList with the order shown by the blade view
Livewire will on each request serialize the public properties, so that it can be sent to the frontend and stored in JavaScript.
Now here's the kicker: JavaScript will do its own internal sorting on objects, which you can't prevent. So to work around that, you have to re-key your array after you sort it, so that the keys are now in ascending order of what you sorted it to.
Basically, all you need to do before you call ->toArray(), is to call ->values() on it, thereby grabbing the values in the order they were, and PHP will assign it new keys starting from 0.
$this->franchiseList = collect($finalFranchiseList)->sortBy('is_available')->reverse()->values()->toArray();
For example, a object like this in JavaScript,
{
1: 'foo',
0: 'bar',
}
Will be internally sorted by JavaScript like this
{
0: 'bar',
1: 'foo',
}
And you can't change that. That's why you need to re-key it.

how to add additional value to array

i have an array, where all data is calculated by records from matches table:
Illuminate\Support\Collection {#1342 ▼
#items: array:4 [▼
"First team" => & array:6 [▼
"points" => 3
"scoredGoals" => 6
"goalsConceded" => 6
"wins" => 0
"loses" => 0
"draws" => 3
]
"Second team" => array:6 [▶]
"third team" => array:6 [▶]
"fourth team" => & array:6 [▶]
]
}
i need add to array image of each team (from teams table, where column image)
how can i do that?
here is my code from controller, where all data is calculated from matches table:
there is my code which i need edit:
$standings = [];
$blank = [
'points' => 0,
'scoredGoals' => 0,
'goalsConceded' => 0,
'wins' => 0,
'loses' => 0,
'draws' => 0,
];
$matches = Match::with('score', 'homeTeam', 'awayTeam')
->whereHas('score', function($query){
$query->whereNotNull('home_team_score')
->whereNotNull('away_team_score');
})
->where('league_id', '=', $league->id)
->get();
foreach ($matches as $match) {
$homeTeamScore = $match->score->home_team_score;
$awayTeamScore = $match->score->away_team_score;
if (! isset($standings[$match->homeTeam->name])) {
$standings[$match->homeTeam->name] = $blank;
}
if (! isset($standings[$match->awayTeam->name])) {
$standings[$match->awayTeam->name] = $blank;
}
$home = &$standings[$match->homeTeam->name];
$away = &$standings[$match->awayTeam->name];
$away['scoredGoals'] += $awayTeamScore;
$home['scoredGoals'] += $homeTeamScore;
$away['goalsConceded'] += $homeTeamScore;
$home['goalsConceded'] += $awayTeamScore;
switch ($homeTeamScore <=> $awayTeamScore) {
case -1:
// home lost
// swap home and away and let it fall through
$tmpHome = &$home;
$home = &$away;
$away = &$tmpHome;
case 1:
// home won
$home['points'] += 3;
$home['wins']++;
$away['loses']++;
break;
default:
// draw
$home['points']++;
$away['points']++;
$home['draws']++;
$away['draws']++;
}
}
$standings = collect($standings)->sort(function ($one, $other) {
if ($one['points'] !== $other['points']) {
return $other['points'] - $one['points']; // similar to desc
}
$oneDelta = $one['scoredGoals'] - $one['goalsConceded'];
$otherDelta = $other['scoredGoals'] - $other['goalsConceded'];
return $otherDelta - $oneDelta; // similar to desc
});
return view('admin.leagues.standings')->with([
'standings' => $standings,
]);
Going with the key of each element in your collection is the name of your team and is stored in the name column of your teams table, you can map over your collection and add in your image.
For example:
$images = [
'First team' => 'first-team.jpg',
'Second team' => 'second-team.jpg',
'Third team' => 'third-team.jpg'
];
$teamsWithImages =
collect([
"First team" => [
"points" => 3,
"scoredGoals" => 6,
"goalsConceded" => 6,
"wins" => 0,
"loses" => 0,
"draws" => 3,
],
"Second team" => [
"points" => 3,
"scoredGoals" => 6,
"goalsConceded" => 6,
"wins" => 0,
"loses" => 0,
"draws" => 3,
],
"Third team" => [
"points" => 3,
"scoredGoals" => 6,
"goalsConceded" => 6,
"wins" => 0,
"loses" => 0,
"draws" => 3,
]
])->map(function ($item, $key) use ($images) {
// You would uncomment this line to retrieve the image
// from your teams table
// You also wouldn't need the use ($images) either
//$item['image'] = Teams::where('name', $key)->first()->image;
$item['image'] = $images[$key];
return $item;
})->all();
dump($teamsWithImages);
Update
Based on the code you've added, you won't need to map you can just add the image in your foreach:
if (! isset($standings[$match->homeTeam->name])) {
$standings[$match->homeTeam->name] = $blank;
$standing[$match->homeTeam->name]['image'] = $match->homeTeam->image;
}
if (! isset($standings[$match->awayTeam->name])) {
$standings[$match->awayTeam->name] = $blank;
$standing[$match->awayTeam->name]['image'] = $match->awayTeam->image;
}
Alternatively you could still use map once you have the standings sorted, but you may as well just add the image in with everything else.
$standingsWithImages = $standings
->map(function ($item, $key) {
$item['image'] = Team::where('name', $key)->first()->image;
return $item;
})->all();

How to get and split Array values in Laravel

Good day I need help on how to get the specific value on an array.I want to get the qty value and id value. The array output is like this
{"items":{"2":{"qty":1,"price":300,"item":{"id":2,"title":"LOTR","author":"James Cameron","price":300,"quantity":150,"created_at":"2020-08-24T13:35:36.000000Z","updated_at":"2020-08-24T13:38:52.000000Z"}}},"totalQty":1,"totalPrice":300}
As for the code
public function postCheckout(Request $request){
if (!Session::has('cart')){
return view('shop.shoppingcart');
}
$oldCart = Session::get('cart');
$cart = new Cart($oldCart);
$order = new Order();
$order->cart = json_encode($cart);
$order->address = $request->input('address');
$order->name = $request->input('name');
Auth::user()->orders()->save($order);
Session::forget('cart');
}
public function findvalarray(){
$order = Order::orderBy('created_at', 'desc')->limit(1)->get();
return view("test", ['order' => $order]);
}
The one with $order->cart = json_encode($cart) is the part where all the products that have been added to cart.
While the findvalarray is the one to find the cart value in the database dont mind the limit cause I need it for selection of a specific date.
And this is the blade view
#foreach($order as $item)
{{$item['cart']}}
#endforeach
Appreaciate the reply thank you
Your $order->cart is in JSON format you need to json_decode() your cart to convert it to array|object so you can access it's value, in your blade you can do
#foreach($order as $item)
{{ dd(json_decode($item['cart'])) }}
#endforeach
The result will be an object that you can access like json_decode($item['cart'])->totalQty
{#260 ▼
+"items": {#258 ▼
+"2": {#257 ▼
+"qty": 1
+"price": 300
+"item": {#251 ▼
+"id": 2
+"title": "LOTR"
+"author": "James Cameron"
+"price": 300
+"quantity": 150
+"created_at": "2020-08-24T13:35:36.000000Z"
+"updated_at": "2020-08-24T13:38:52.000000Z"
}
}
}
+"totalQty": 1
+"totalPrice": 300
}
If you want it as array you can do dd(json_decode($item['cart'], true)) this will give you
array:3 [▼
"items" => array:1 [▼
2 => array:3 [▼
"qty" => 1
"price" => 300
"item" => array:7 [▼
"id" => 2
"title" => "LOTR"
"author" => "James Cameron"
"price" => 300
"quantity" => 150
"created_at" => "2020-08-24T13:35:36.000000Z"
"updated_at" => "2020-08-24T13:38:52.000000Z"
]
]
]
"totalQty" => 1
"totalPrice" => 300
]
And you can access it like json_decode($item['cart'])['totalQty']

merging nested lists and map in ruby

I have following list of maps, how can I get values inside map out and merge them as a new list
Example:
x = [ { "key1" => [{"K1" =>"123", "K2" =>"123"}] },
{ "key1" => [{"K3" =>"23", "K4" =>"32"}] },
{ "key1" => [{"K5" =>"34", "K6" =>"23"}] }]
What I want is:
[{"K1" =>"123", "K2" =>"123"},
{"K3" =>"23", "K4" =>"32"},
{"K5" =>"34", "K6" =>"23"}]
You can try the below -
x = [ { "key1" => [{"K1" =>"123", "K2" =>"123"}] },
{ "key1" => [{"K3" =>"23", "K4" =>"32"}] },
{ "key1" => [{"K5" =>"34", "K6" =>"23"}] }]
y = x.map{|h| h.map{|i,j| j} }.flatten
print(y)
This prints the below
[{"K1"=>"123", "K2"=>"123"}, {"K3"=>"23", "K4"=>"32"}, {"K5"=>"34", "K6"=>"23"}]
x.flat_map(&:entries).group_by(&:first).map{|k,v| Hash[k, v.map(&:last)]}
as:
> x = [ { "key1" => [{"K1" =>"123", "K2" =>"123"}] },
{ "key1" => [{"K3" =>"23", "K4" =>"32"}] },
{ "key1" => [{"K5" =>"34", "K6" =>"23"}] }]
> x.flat_map(&:entries).group_by(&:first).map{|k,v| Hash[k, v.map(&:last)]}
=> [{"key1"=>[[{"K1"=>"123", "K2"=>"123"}], [{"K3"=>"23", "K4"=>"32"}], [{"K5"=>"34", "K6"=>"23"}]]}]
I hope that helpful
You can simply do as below,
x.map { |z| z.values[0][0] }
# => [{"K1"=>"123", "K2"=>"123"}, {"K3"=>"23", "K4"=>"32"}, {"K5"=>"34", "K6"=>"23"}]

Ruby pick up a value in hash of array to reformat into a hash

Is there a way I can pick a value in hash of array, and reformat it to be only hash?
Is there any method I can do with it?
Example
[
{
"qset_id" => 1,
"name" => "New1"
},
{
"qset_id" => 2,
"name" => "New2"
}
]
Result
{
1 => {
"name" => "New1"
},
2 => {
"name" => "New2"
}
}
You can basically do arbitary manipulation using reduce function on array or hashes, for example this will get your result
array.reduce({}) do |result, item|
result[item["qset_id"]] = { "name" => item["name"] }
result
end
You can do the same thing with each.with_object do:
array.each.with_object({}) do |item, result|
result[item["qset_id"]] = { "name" => item["name"] }
end
it's basically the same thing but you don't have to make each iteration return the result (called a 'memo object').
You could iterate over the first hash and map it into a second hash:
h1.map{|h| {h['qset_id'] => {'name' => h['name']}} }
# => [{1=>{"name"=>"New1"}}, {2=>{"name"=>"New2"}}]
... but that would return an array. You could pull the elements into a second hash like this:
h2 = {}
h1.each do |h|
h2[h['qset_id']] = {'name' => h['name']}
end
>> h2
=> {1=>{"name"=>"New1"}, 2=>{"name"=>"New2"}}

Resources