Sorting stdClass Object in two - php

I want sorting Teams list by "terminland_days" value
I read same question in Stack Overflow https://stackoverflow.com/a/38237197/5006328 but still have problem on this.
This is my PHP (PHP >=7.4) code:
public function display($tpl = null) {
// myval get from other model
//print_r ($myval);
$myval = Array
(
[0] => stdClass Object
(
[id] => 1
[state] => 1
[teams] => {"teams0":{"name":"Jhon","terminland_days":"3"},"teams1":{"name":"Alex","terminland_days":"2"}}
[distance] => 5839.5147520164
)
[1] => stdClass Object
(
[id] => 2
[state] => 1
[teams] => {"teams0":{"name":"Jeff","terminland_days":"12"},"teams1":{"name":"Fred","terminland_days":"1"}}
[distance] => 5839.5147520164
)
);
foreach ($myval as $item) {
$paramsteam = json_decode($item->teams);
foreach ($paramsteam as $team) {
// i want sorting Teams as "terminland_days" value
usort($team, "compare_func");
// error ==> Warning: usort() expects parameter 1 to be array, object given
echo $team->terminland_days;
}
}
}
public function compare_func($a, $b)
{
if ($a->terminland_days == $b->terminland_days) {
return 0;
}
return ($a->terminland_days < $b->terminland_days) ? -1 : 1;
// You can apply your own sorting logic here.
}
as I understand, I must use usort, please help me how I can do it?
When print_r ($team); output:
stdClass Object
(
[name] => Jhon
[terminland_days] => 3
)
stdClass Object
(
[name] => Alex
[terminland_days] => 2
)
stdClass Object
(
[name] => Jeff
[terminland_days] => 12
)
stdClass Object
(
[name] => Fred
[terminland_days] => 1
)

After a few hours of scrutiny, I realized that the best way was to first convert the object to an array and then sort it. so :
$paramsteam = json_decode($item->teams,true);
usort($paramsteam, function ($item1, $item2) {
return $item1['terminland_days'] <=> $item2['terminland_days'];
});
foreach ($paramsteam as $team) {
echo $team['terminland_days'];
}
also #Nico haase thank you

Related

Extracting a property from an array of an array of objects

I've got an object, containing an array of objects, containing an array of values:
stdClass Object (
[devices] => Array (
[0] => stdClass Object (
[location] => 1
[delegate] =>
[type] => 1
[id] => 1234
[IP] => 1.2.3.4
[name] => host1
[owner] => user6
[security] => 15
)
[1] => stdClass Object (
[location] => 2
[delegate] =>
[type] => 1
[id] => 4321
[IP] => 4.3.2.1
[name] => host2
[owner] => user9
[security] => 15
)
)
)
I want to extract just the id and name into an array in the form of:
$devices['id'] = $name;
I considered using the array_map() function, but couldn't work out how to use it... Any ideas?
This will generate you a new array like I think you want
I know you says that delegate is an object but the print does not show it that way
$new = array();
foreach($obj->devices as $device) {
$new[][$device->id] = $device->name;
}
Would something like this not work? Untested but it cycles through the object structure to extract what I think you need.
$devices = myfunction($my_object);
function myfunction($ob){
$devices = array();
if(isset($ob->devices)){
foreach($ob->devices as $d){
if(isset($d->delegate->name && isset($d->delegate->id))){
$devices[$d->delegate->id] = $d->delegate->name;
}
}
}
return($devices);
}
Im usually using this function to generate all child and parent array stdclass / object, but still make key same :
function GenNewArr($arr=array()){
$newarr = array();
foreach($arr as $a=>$b){
$newarr[$a] = is_object($b) || is_array($b) ? GenNewArr($b) : $b ;
}
return $newarr;
}

Sorting an StdClass Object Array by the values of another array

I have an StdClass Array. Each object is ordered like this (there are about 50 objects in the array, but I thought I'd just put one to show the structure):
stdClass Object (
[display_name] => Bob Simons
[post_title] => Lesson 1
[meta_value] => 100
[comment_approved] => passed
[c_num2] => 26
[term_id] => 3
)
I have another array that looks like this:
Array (
[0] => 3
[1] => 4
[2] => 5
[3] => 16
[4] => 17
[5] => 18
[6] => 19
[7] => 20
[8] => 21
)
The second array defines the sorting of the first one based on the [term_id] field. So essentially, everything with the [term_id] 3 should be at the top of the array, everything with the [term_id] 4 should be next, all based on that second array.
I am trying desperately to figure out how to do this, I've been looking at usort and the like but at a total loss.
I hope someone can help and will be really grateful.
Try this
$sortedArray = [];
foreach ($order as $termId) {
foreach ($objects as $object) {
if ($object->term_id == $termId) {
$sortedArray[] = $object;
}
}
}
$objects holds your stdClass instances and $order your list with the ordered term ids.
In the case the term_id should always order in an ascending way, you can use usort:
usort($objects, function ($obj1, $obj2) {
if ($obj1->term_id == $obj2->term_id) {
return 0;
}
return ($obj1->term_id < $obj2->term_id) ? -1 : 1;
});

Retrieving correct record from multidimentional array

I'm having a mental freeze moment. If I have an array in the following format:
$myData = Array
(
[0] => stdClass Object
(
[id] => 1
[busID] => 5
[type] => SMS
[number] => 5128888888
)
[1] => stdClass Object
(
[id] => 2
[busID] => 5
[type] => APP
[number] => 5125555555
)
[2] => stdClass Object
(
[id] => 4
[busID] => 5
[type] => APP
[number] => 5129999988
[verified] => 1
[default] => 0
)
)
And I only have an var for ID of the record, how do I retrieve the rest of the detail for that set.
$myID = 2;
// get number 5125555555 and it's type
echo $myData[][$myID]['number']; // ???
The way you have your data arranged your going to have to loop through your array to identify the object corresponding to $myID.
foreach($myData as $object) if($object->id == $myID) echo $object->number;
The alternative is to arrange your $myData as an associative array with the id field as the key. Then you could access it simply with $myData[$myID]->number.
Actually it's an array that contains StdClass objects , try looping over $myData and access each attribute :
foreach ( $myData as $data )
{
print_r($data->id);
// ...
}
You can avoid loop by using following logic:
<?php
$myID = 2;
$myData = json_decode(json_encode($myData),1); // Convert Object to Array
$id_arr = array_column($myData, 'id'); // Create an array with All Ids
$idx = array_search($myID, $id_arr);
if($idx !== false)
{
echo $myData[$idx]['type'] . ' -- ' . $myData[$idx]['number'];
}
?>
Working Demo
Note: array_column is supported from PHP 5.5.
For lower versions you can use this beautiful library https://github.com/ramsey/array_column/blob/master/src/array_column.php
You can create a custom function to achieve this, you need to pass the array and id whose details you want and the function will return the array with matching id, like below
function detailsById($myData,$id){
foreach($myData as $data){
if($data->id == $id){
return $data;
}
}
}
Just call this function with your array and id..
$data=detailsById($myData,2);
echo "<pre>";print_r($data);
This will give you :
stdClass Object
(
[id] => 2
[busID] => 5
[type] => APP
[number] => 5125555555
)
And further to print 'number' and 'type' use $data array
$data['type'];
$data['number'];

sort mysql rows by column?

I have following sql query:
SELECT job_id, job_type FROM jobs
I'm getting the following result (set of rows) from mysql query:
RESULT (print_r):
Array
(
[0] => stdClass Object
(
[job_id] => 239
[job_type] => 'type1';
}
[1] => stdClass Object
{
[job_id] => 53
[job_type] => 'type2';
}
[2] => stdClass Object
{
[job_id] => 76
[job_type] => 'type3';
}
[3] => stdClass Object
{
[job_id] => 78
[job_type] => 'type1';
}
)
As you can see I've got three types of job: type1, type2, type3
Is there any way to map/regroup these results by job_type?
Basically I'd like to have something similar to this:
Array
(
['type1'] => Array (
[0] => stdClass Object
{
[job_id] => 239
[job_type] => 'type1';
}
[1] => stdClass Object
{
[job_id] => 76
[job_type] => 'type1';
}
)
['type2'] => Array (
[0] => stdClass Object
{
[job_id] => 53
[job_type] => 'type2';
}
)
['type3'] => Array (
[0] => stdClass Object
{
[job_id] => 78
[job_type] => 'type3';
}
)
)
Or maybe I should use different query?
I've tried to use array_map() with no luck, but I was getting only one array with elements from only one job_type.
Thanks in advance.
You cannot do this with predefined PHP functions. But you can do it yourself pretty easily.
For example: Assuming you have your MySQL result as written in your question in a variable called $rows, you can do the following to get the desired map.
$map = array();
foreach($rows as $row) {
if (!isset($map[$row->job_type])) {
$map[$row->job_type] = array($row);
} else {
$map[$row->job_type][] = $row;
}
}
Now $map contains your desired array.
Unfortunately for this task does not have a native solution in pure PHP/MySQL. So You need to sort it on PHP side manualy. I think You should write function for this an use it when You need
function sortBy($array, $key, $sortKeys=false){
// I don't test this function, just write it for answer, so it may contain errors
$tmp = array();
foreach($array as $k=>$v){
$tmp[$array[$k][$key]][] = $v;
}
if($sortKeys)
ksort($tmp);
return $tmp;
}
And use it like
print_r(sortBy(mySQLSelect(),'job_type'));

PHP: What causes usort() to turn array into 1?

Can't get why usort() turns array into 1
Here is code of my sorting callback method in SomeClass
protected $_sortKey = '';
public function setSortKey($keyname)
{
$this->_sortKey = $keyname;
}
public function sortByKeyValue($a, $b)
{
$key = $this->_sortKey;
if ($a->$key == $b->$key) {
return 0;
}
return ($a->$key < $b->$key) ? -1 : 1;
}
Here is code where sorting takes place
$someObj = new SomeClass();
$someObj->setSortKey('name');
$sorted_stuff = usort($stuff_to_sort, array($someObj, 'sortByKeyValue'));
where $stuff_to_sort is:
Array
(
[0] => stdClass Object
(
[id] => 57
[status] => ACTIVE
[updated] => 2010-09-17T12:16:25Z
[name] => Windows Server 2008 SP2 x64 - MSSQL2K8R2
)
[1] => stdClass Object
(
[id] => 62
[status] => ACTIVE
[updated] => 2010-10-19T17:16:55Z
[name] => Red Hat Enterprise Linux 5.5
)
)
and $sorted_stuff gets value 1 instead of sorted array. What is wrong ?
PHP 5.2.17
see http://docs.php.net/function.usort:
bool usort ( array &$array , callback $cmp_function )
The sorted array is not the return value. usort() alters the array you're passing as the first argument.

Categories