Laravel /PHP Getting the keys from an array - php

I have a collection
Collection {#364 ▼
#items: array:2 [▼
24 => Collection {#375 ▼
#items: array:3 [▶]
}
0 => Collection {#376 ▶}
]
}
I try and convert to an array grab the keys and sort them
dd(sort(array_keys($group_ids->toarray())));
I get the error Only variables should be passed by reference
I need to convert this collection to an array of the keys in ascending order.
dd(array_keys($group_ids->toArray()));
seems to give what I need but I cannot convert it.
array:2 [▼
0 => 24
1 => 0
]

The Only variables should be passed by reference error is thrown because of the PHP's sort() function requires a reference and it can only be a variable not a return value from another function. To solve this error you can just use an intermediate variable like this:
$keys = array_keys($group_ids->toArray());
sort($keys);
Since you already using Laravel Collection, you can just use the keys() and the sort() methods instead. Suppose the $group_ids is an instance of Collection, you can extract the key and sort it ascendingly like this:
$sortedKeys = $group_ids->keys()->sort()->toArray();
Hope this help!

Below Solution is may be work for you.
When you call User::all() you get something like this:
0 => points: 10
1 => points: 50
2 => points: 30
3 => points: 70
4 => points: 20
What you can do is using the values() function, which will reset the keys of you collection:
0 => points: 70
1 => points: 50
2 => points: 30
3 => points: 20
4 => points: 10
May be you have try to sort data from the value. so key is automatically sorting out.
$users = User::all();
$users = $users->sortByDesc(function($item){
return $item->points()->sum('amount');
})->values();
I am not sure about this solution but hope it helps little bit with your question. in your question i didn't see any query so i have no much how you generate that collections.
Thanks

Related

Getting same result When accessing Plain Array and Collection Array in Laravel upgrade 5.2 to 5.3

I've upgraded our Laravel application from Laravel 5.2 to 5.3 and got a warning message from Laravel side
The Query Builder returns collections, instead of plain arrays, in
Laravel 5.3. You will need to upgrade your code to use collections or
chain the all() method onto your query to return a plain array.
Thats means fluent query builder now returns
Illuminate\Support\Collection instances instead of plain arrays. This
brings consistency to the result types returned by the fluent query
builder and Eloquent.
You can standard this by below example
Laravel 5.2
$users = DB::table('users')->select('id','first_name')->limit(10)->get();
dd($users);
Result :
==========
array:10 [▼
0 => {#1423 ▼
+"id": 12
+"first_name": "John"
}
1 => {#1424 ▶}
2 => {#1425 ▶}
3 => {#1426 ▶}
4 => {#1427 ▶}
5 => {#1428 ▶}
6 => {#1429 ▶}
7 => {#1430 ▶}
8 => {#1431 ▶}
9 => {#1432 ▶}
]
Laravel 5.3
$users = DB::table('users')->select('id','first_name')->limit(10)->get();
dd($users);
Result :
==========
Collection {#1428 ▼
#items: array:10 [▼
0 => {#1430 ▼
+"id": 12
+"first_name": "John"
}
1 => {#1431 ▶}
2 => {#1432 ▶}
3 => {#1433 ▶}
4 => {#1434 ▶}
5 => {#1435 ▶}
6 => {#1436 ▶}
7 => {#1437 ▶}
8 => {#1438 ▶}
9 => {#1439 ▶}
]
}
When I am trying to access data by $users[0]->first_name getting same result thats is correct.
That creates confusion for me.. What is the actual difference here and what will be the impact on our application?
Laravel collections implement "Arrayable" which means they inherit all of the same functionality as normal arrays but also have the additional functionality that collections provide, so you will not get any issues accessing at index.
If you want to convert it back to a normal array, you could do ->toArray()
$users = DB::table('users')->select('id','first_name')->limit(10)->get()->toArray();
I was worried about Array and Collection elements and lastly i know
That Collection class holds the collection elements in a protected
property called $items (as you could see from your dump protected
'items' =>), which is of type array. The class also implements an
interface called IteratorAggregate, which basically means it allows
any variable of that type to be iterated using a foreach statement.
So in short Collection is an iterable object that can be treated as an array, but is better than an array because if offers extra methods that allow you to manipulate the items from the collection. You can check the Collection API to see a complete list of available methods.
Ref : In a Laravel 5 Collection how do you return an array of objects instead of an array of arrays?

Parsing a nested array where key is a float in php

I have the following query that I need to get a value from a nested array. I'm using laravel 5.4 in case that matters.
$usersstyle = DB::connection('mysql2')
->table('wp_rg_lead_detail')
->where('lead_id', $collection->id)
->get();
dd($usersstyle);
This has an output of:
Collection {#396 ▼
#items: array:49 [▼
0 => {#406 ▶}
1 => {#407 ▶
18 => {#428 ▼
+"id": 655
+"lead_id": 67
+"form_id": 8
+"field_number": 51.0
+"value": "Yes"
}
19 => {#429 ▼
+"id": 656
+"lead_id": 67
+"form_id": 8
+"field_number": 6.1
+"value": "Sleeveless"
}
20 => {#430 ▼
+"id": 657
+"lead_id": 67
+"form_id": 8
+"field_number": 6.2
+"value": "Jacket"
}
21 => {#431 ▼
+"id": 658
+"lead_id": 67
+"form_id": 8
+"field_number": 6.3
+"value": "Cardigan"
}
22 => {#432 ▶}
I have tried the following, but it returns the 1st instance of the field_number, and ignores the 6.2 and 6.3. How do I do this and keep all the floats as keys.
$keyed = $usersstyle->keyBy('field_number')->all();
I want to get something like the below. With out a foreach loop to display that.
echo $6.3->value;
with the result being Cardigan
I have also used
$grabvalues = $usersstyle->whereIn('field_number', 80.3)->toArray();
this returns an array or if i drop the toArray a collection that I still need to loop through to get the value
Try this : This doc may help you .
$plucked = $usersstyle->pluck('field_number', 'value');
$plucked->all();
Another way :
$fieldValue = $usersstyle->map(function ($users) {
return collect($users->toArray())
->only(['field_number', 'value'])
->all();
});
Well after a bunch of test.. Here is the answer I came up with that worked for me. if someone knows how to write this better please submit.
$usersstyle = DB::connection('mysql2')
->table('wp_rg_lead_detail')
->where('lead_id', $collection->id)
->get()
;
$newkeys = $usersstyle->pluck('field_number');
$values = $usersstyle->pluck('value');
$result = $newkeys->combine($values)->toArray();
dd($result["6.1"]);

Laravel (5.3) pluck collection is returning other results than array

I've encoutered something strange. I'm making a selectbox, and i'm using the pluck method on a database model.
This piece of code:
$orgs = Organisation::pluck('name', 'id');
dd($orgs);
Gives me the following results:
Collection {#611 ▼
#items: array:6961 [▼
0 => "Test organisatie"
1 => "Name"
2 => "Another"
As you can see, the ID is not present.
Now when i make it into an array:
$orgs = Organisation::pluck('name', 'id')->toArray();
dd($orgs);
It gives the following results:
array:6961 [▼
1 => "Test organisatie"
3 => "Name"
19 => "Another"
The array is perfectly usable, i just don't understand why there's a difference.
--Edit:
When i use the collection in the select form helper, it does display the keys properly. Making me think it's a bug in the var dumper?
#Patrick Vd Pols
could you please try as below
Organisation::pluck('name','id')->all();

Sort multi-dimensional array

I have a multi dimensional array in the following form
array:2 [▼
"dashboardData" => array:1 [▶]
"widgetData" => array:5 [▼
0 => {#214 ▼
+"_id": "575fcf6d298fbfd833000041"
+"created": "2016-06-14T09:33:33.492Z"
+"dashboardid": "575fcebc298fbfd833000036"
+"datasource": {#215 ▶}
}
1 => {#249 ▶}
2 => {#285 ▶}
3 => {#297 ▶}
4 => {#333 ▶}
]
]
I have deleted a lot of data but the above just be enough to demonstrate what I am after. Essentially, the widgetData part of my array has a random order for its elements.
As you can see above though, each element in this part of my array has a created value. Is it possible to order just this part of my array (widgetData) based on the created date?
Thanks
Because your dates are using standard UTC date strings, you can sort your array by iterating the components and assigning the values to the original array (assuming it's variable), i.e:
let arrayCopy = array
for index in 0..<arrayCopy.count {
if let widgetData: [[String: AnyObject]] = array[index]["widgetData"] as? [[String: AnyObject]] {
let sortedWidgetData = widgetData.sort({ (dictionary1, dictionary2) -> Bool in
return (dictionary1["created"] as! String) < (dictionary2["created"] as! String)
})
array[index]["widgetData"] = sortedWidgetData
}
}
You could also just do this at runtime on your datasource as and when it's needed.

Add simple array to Collection

in laravel this method is return Collection type of result:
$all_currency = CurrencyType::lists('currency_type', 'id');
Result:
Collection {#687 ▼
#items: array:2 [▼
1 => "EUR"
2 => "CHF"
]
}
now and i want to add -1 => "USD" to that. but i cant do it. my solution create nested array into that. for example:
$all_currency->push (["-1"=>"11"]);
Result:
Collection {#687 ▼
#items: array:4 [▼
1 => "EUR"
2 => "CHF"
3 => array:1 [▼
-1 => "USD"
]
]
}
If you need to use array, you can try to convert collection to an array with toArray() method:
$all_currency = CurrencyType::pluck('currency_type', 'id')->toArray();
$all_currency['-1'] = '11';
If you need to use collection, use put() helper:
$all_currency = CurrencyType::pluck('currency_type', 'id')->put('-1', '11');
Also, lists() is deprecated and will be removed in future, use pluck() instead.
Did you try to cast the collection to array before adding the currency?
Otherwise, it might help to check out the interface of the Collection class. Since you didn't mention it, it could be Doctrine or Propel or something else?
You then might find out, that there is a special function for adding a key-value pair, since pushing a value, adds that value (an array in your case) to the collection which is not what you want.
There might be no way of adding a value to a specific key index -1, that all depends on which ORM you are actually using and it's implementation.
//edit:
It seems the correct method is put and the code should look like this:
$all_currency->push (-1, "11");
https://laravel.com/api/master/Illuminate/Support/Collection.html#method_put
Use the put() method on your collection:
$all_currency->put(-1, "USD");
You can see all available methods for collections here: Collections

Categories