php array multisort by inner arrays value [duplicate] - php

This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 7 years ago.
I am trying to sort vote-list in PHP.
The list is an array, containing class-objects:
Array
(
[0] => VotedSong Object
(
[title] => SimpleXMLElement Object
(
[0] => bbh - bghs dsdw
)
[votes] => SimpleXMLElement Object
(
[0] => 6
)
[key] => SimpleXMLElement Object
(
[0] => bbh--0
)
)
[1] => VotedSong Object
(
[title] => SimpleXMLElement Object
(
[0] => aaa - bbb
)
[votes] => SimpleXMLElement Object
(
[0] => 4
)
[key] => SimpleXMLElement Object
(
[0] => aaa--0
)
)
[2] => VotedSong Object
(
[title] => SimpleXMLElement Object
(
[0] => wdewv - qwdqs
)
[votes] => SimpleXMLElement Object
(
[0] => 3
)
[key] => SimpleXMLElement Object
(
[0] => wdewv--0
)
)
[3] => VotedSong Object
(
[title] => SimpleXMLElement Object
(
[0] => Hsg and fdSv - aGamaama
)
[votes] => SimpleXMLElement Object
(
[0] => 2
)
[key] => SimpleXMLElement Object
(
[0] => hsgandfdsv--0
)
)
)
I managed to sort there by the ->key wich is working fine:
usort($votedsongs, function ($a, $b) { return $b->votes - $a->votes; });
But after this, I still need another sort-function to sort those songs that have the same amout of votes by ->title.
I already found some solutions that deal with problems alike, but those did not work for me.
Any ideas on this?

Sounds like you are wanting to sort the VotedSong objects in the array by votes and then by title (which is misspelled as titel). If so, this could work:
usort($votedsongs, function ($a, $b) {
if ($b->votes == $a->votes) {
return ($a->title < $b->title) ? -1 : 1;
}
return $b->votes - $a->votes;
});

Thanks to splash58 for this solution:
if (!($r = $b->votes - $a->votes)) $r = strcmp($b->title, $a->title); return $r;
I modified the alphabetic sort to be non-casesensitive and switched $a->title and $b->title - that's it:
usort($votedsongs, function ($a, $b) {
if (!($r = $b->votes - $a->votes)) $r = strcasecmp($b->title, $a->title); return $r;
});

Related

json array sort by value in php

I have JSON arrays of objects. I am trying to sort an array using usort. I want to use value field from field_listing_order. It sorted using value. I am missing something but not able to figure it out. please review the code. Thanks!
stdClass Object
(
[node_title] => abc
[nid] => 2281
[field_api_order_value] => 201
[field_node_entity_type] => node
[_data] => Array
(
[nid] => Array
(
[entity_type] => node
[entity] => stdClass Object
(
[title] => abc
[field_listing_order] => Array
(
[und] => Array
(
[0] => Array
(
[value] => 8
[format] =>
[safe_value] => 8
)
)
)
)
)
)
)
stdClass Object
(
[node_title] => abc
[nid] => 2243
[field_api_order_value] => 204
[field_node_entity_type] => node
[_data] => Array
(
[nid] => Array
(
[entity_type] => node
[entity] => stdClass Object
(
[title] => abc
[field_listing_order] => Array
(
[und] => Array
(
[0] => Array
(
[value] => 3
[format] =>
[safe_value] => 3
)
)
)
)
)
)
) stdClass Object
(
[node_title] => abc
[nid] => 2431
[field_api_order_value] => 242
[field_node_entity_type] => node
[_data] => Array
(
[nid] => Array
(
[entity_type] => node
[entity] => stdClass Object
(
[title] => abc
[field_listing_order] => Array
(
[und] => Array
(
[0] => Array
(
[value] => 1
[format] =>
[safe_value] => 1
)
)
)
)
)
)
)
and So on ...
foreach ($view->result as $result) {
$node = $result->_data['nid']['entity'];
$listing_order = $node->field_listing_order[LANGUAGE_NONE][0];
.....
// code goes here and it works well. sorting issue
}
usort ($node->field_listing_order[LANGUAGE_NONE][0], function($a, $b){
return strcmp($a->value, $b->value);
}); ?>
If you need to sort all the nodes using the field_listing_order value, you need to compare the values along the full path, from the first object to the value:
usort($view->result, function($a, $b) {
$la = $a->_data['nid']['entity']->field_listing_order[LANGUAGE_NONE][0]['value'];
$lb = $b->_data['nid']['entity']->field_listing_order[LANGUAGE_NONE][0]['value'];
return $la - $lb ;
});
In this case $a and $b are two different nodes which could be compared. That why you should compare the field_listing_order's value of these nodes. The answer is working with $la- $lb

PHP Sorting Multidimensional Associative Array by Key and Value

I'm trying to sort the following data by the date in the key and the value of Name.
The aim is to a get nice date ordered array with all the Names from the inner array in alphabetical order.
Array
(
[2017-07-27] => Array
(
[0] => stdClass Object
(
[Job] => stdClass Object
(
[Name] => Orange
)
)
[4] => stdClass Object
(
[Job] => stdClass Object
(
[Name] => Apple
)
)
)
[2017-07-22] => Array
(
[6] => stdClass Object
(
[Job] => stdClass Object
(
[Name] => Apple
)
)
[7] => stdClass Object
(
[Job] => stdClass Object
(
[Name] => Orange
)
)
)
[2017-07-29] => Array
(
[9] => stdClass Object
(
[Job] => stdClass Object
(
[Name] => Orange
)
)
[11] => stdClass Object
(
[Job] => stdClass Object
(
[Name] => Plumb
)
)
)
)
I'm pretty sure I should be using array_multisort but can't quite get the desired results.
You must split the code if you want to order on object properties, use the usort function.
Where $arr is your array:
uksort($arr, 'dateCmp');
foreach($arr as &$sub){
usort($sub, 'propCmp');
}
function dateCmp($a, $b){
return (strtotime($a) < strtotime($b) ? -1 : 1);
}
function propCmp($a, $b){
return ($a->Job->Name < $b->Job->Name ? -1 : 1);
}
Please try below code,
$sorted_vals = array();
ksort($multiArrs);
foreach($multiArrs as $key => $value) { // $multiArrs = your data array
$columns = null;
foreach ($value as $index => $element) {
$columns[] = $element->Job;
}
$temp = $value;
array_multisort($columns, SORT_ASC, $temp);
$sorted_vals[$key] = $temp;
}

convert multidimensional array to object in php [duplicate]

This question already has answers here:
PHP - recursive Array to Object?
(17 answers)
Closed 6 years ago.
i have seen a lot of examples but was unsuccessful to help myself. I have a multidimensional array that i want to convert to object format. I tried going levels deeper (multidimensional) but that all. I want to make it an php object. This is my scenario
// this is my array
Array
(
[_cars] => Array
(
[_car] => Array
(
[0] => Array
(
[_types] => Array
(
[_type] => Array
(
[0] => Array
(
[_cc] => 100
)
[1] => Array
(
[_cc] => 100
)
[2] => Array
(
[_cc] => 1000
)
)
)
)
)
)
)
)
// this is what i want
[_cars] => stdClass Object
(
[_car] => Array
(
[0] => stdClass Object
(
[_types] => stdClass Object
(
[_type] => Array
(
[0] => stdClass Object
(
[_cc] => 999999999999
)
[1] => stdClass Object
(
[_cc] => 999999999999
)
[2] => stdClass Object
(
[_cc] => 999999999999
)
)
)
)
)
)
Not sure if it will work but you can try
$object = json_decode(json_encode($array));
Please check this if this okay
$obj = new stdClass($array); or
$obj = json_decode(json_encode($array));

PHP Custom Sort Multi-Dimensional Array by DateTime Field

I searched for this, and it seems the ones similar to this are all going to be "custom" based on the poster's original array structure.
I'm struggling with getting the array below sorted by the [DateTime] key of each entry. I'd like them sorted Ascending (newest datetime with the highest array index), and would like to retain the array structure and keys if possible.
Array
(
[0] => Array
(
[Source] => SimpleXMLElement Object
(
[0] => RTU-12 Merchandise Support, Fan Status Switch
)
[EventType] => SimpleXMLElement Object
(
[0] => Alarm Recall
)
[Description] => SimpleXMLElement Object
(
[0] => No Flow
)
[DateTime] => 07-25-2015 20:09:47
[Priority] => SimpleXMLElement Object
(
[0] => Medium
)
[SubSystemKey] => SimpleXMLElement Object
(
[0] => 2
)
[ViewKey] => SimpleXMLElement Object
(
[0] => 7
)
)
[1] => Array
(
[Source] => SimpleXMLElement Object
(
[0] => RTU-03 Checkout Area, Fan Status Switch
)
[EventType] => SimpleXMLElement Object
(
[0] => Alarm Recall
)
[Description] => SimpleXMLElement Object
(
[0] => No Flow
)
[DateTime] => 07-25-2015 20:09:44
[Priority] => SimpleXMLElement Object
(
[0] => Medium
)
[SubSystemKey] => SimpleXMLElement Object
(
[0] => 2
)
[ViewKey] => SimpleXMLElement Object
(
[0] => 7
)
)
... SOME INDICES REMOVED FOR READABILITY ...
[12] => Array
(
[Source] => SimpleXMLElement Object
(
[0] => ~RackA\SGr2\Cmp4, Proof of Running
)
[EventType] => SimpleXMLElement Object
(
[0] => Alarm Recall
)
[Description] => SimpleXMLElement Object
(
[0] => No Proof
)
[DateTime] => 07-25-2015 19:39:13
[Priority] => SimpleXMLElement Object
(
[0] => Medium
)
[SubSystemKey] => SimpleXMLElement Object
(
[0] => 1
)
[ViewKey] => SimpleXMLElement Object
(
[0] => 2
)
)
[13] => Array
(
[Source] => SimpleXMLElement Object
(
[0] => ~RackC\SGr1, Suction Pressure
)
[EventType] => SimpleXMLElement Object
(
[0] => Alarm
)
[Description] => SimpleXMLElement Object
(
[0] => Pressure too high
)
[DateTime] => 07-25-2015 19:14:21
[Priority] => SimpleXMLElement Object
(
[0] => Medium
)
[SubSystemKey] => SimpleXMLElement Object
(
[0] => 1
)
[ViewKey] => SimpleXMLElement Object
(
[0] => 4
)
)
[Count] => 14
[NewEvents] => 14
[Result] => Success
)
Here is what I've tried so far:
function date_compare($a, $b)
{
$t1 = strtotime($a['DateTime']);
$t2 = strtotime($b['DateTime']);
return $t1 > $t2;
}
usort($alarms, 'date_compare');
My results are simply an unsorted (and seemingly broken organization) array. I'm not too skilled with usort's, so looking for some guidance.
Thanks!
It seems strtotime() doesn't parse this date format: 07-25-2015 19:39:13, which is confirmed by some quick experimentation:
var_dump(strtotime("07-25-2015 19:39:13"));
bool(false)
var_dump(strtotime("07/25/2015 19:39:13"));
int(1437845953)
A detailed list of date formats usable by strtotime() is available here:
http://php.net/manual/en/datetime.formats.date.php
The quickest way to solve this is to convert the dashes into slashes:
function date_compare($a, $b) {
$t1 = strtotime(str_replace('-', '/', $a['DateTime']));
$t2 = strtotime(str_replace('-', '/', $b['DateTime']));
return $t1 > $t2;
}
usort($alarms, 'date_compare');
You might want to use uasort() to preserve the keys of your array.
http://php.net/manual/en/function.uasort.php
Also consider this:
The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
http://php.net/manual/en/function.usort.php
Therefore:
function date_compare($a, $b) {
$t1 = strtotime(str_replace('-', '/', $a['DateTime']));
$t2 = strtotime(str_replace('-', '/', $b['DateTime']));
return $t1 > $t2 ? -1 : 1;
}
uasort($alarms, 'date_compare');
You could also use array_multisort with a "NATURAL" flag.
$dateTime = array();
foreach ($array as $tempArray) {
$dateTime[] = $tempArray["DateTime"];
}
array_multisort($dateTime, SORT_NATURAL, $array);
Got some help from
http://shiflett.org/blog/2011/jun/sorting-multi-dimensional-arrays-in-php

Sort multidimensional array recursive by specific key

I'm trying to sort this array recursively by its label:
Array
(
[0] => Array
(
[id] => 6
[label] => Bontakt
[children] => Array
(
)
)
[1] => Array
(
[id] => 7
[label] => Ampressum
[children] => Array
(
[0] => Array
(
[id] => 5
[children] => Array
(
)
[label] => Bome
)
[1] => Array
(
[id] => 8
[children] => Array
(
)
[label] => Aome
)
[2] => Array
(
[id] => 10
[children] => Array
(
)
[label] => Come
)
)
)
[2] => Array
(
[id] => 9
[label] => Contakt
[children] => Array
(
)
)
[3] => Array
(
[id] => 11
[label] => Dead
[children] => Array
(
)
)
)
I've read several Questions, and I feel to be pretty close, but I can't figure out what's not working:
function sortByAlpha($a, $b)
{
return strcmp(strtolower($a['label']), strtolower($b['label'])) > 0;
}
function alphaSort(&$a)
{
foreach ($a as $oneJsonSite)
{
if (count($oneJsonSite["children"]) > 0) alphaSort($oneJsonSite["children"]);
}
usort($a, 'sortByAlpha');
}
alphaSort($jsonSites);
Current output is like this:
Ampressum
Bome
Aome
Come
Bontakt
Contakt
Dead
The children elements are not sorted...
Check this out:
In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference.
(Picked from here: http://php.net/manual/en/control-structures.foreach.php)
You should try it with this one:
function alphaSort(&$a)
{
foreach ($a as &$oneJsonSite)
{
if (count($oneJsonSite["children"]) > 0) alphaSort($oneJsonSite["children"]);
}
usort($a, 'sortByAlpha');
}

Categories