Sort array with 2 conditions - php

I am trying to create a golf livescore leaderboard, but am having one issue. I would like to order the array by who has the lowest points, but also, if 2 or more have the same points, order those by which hole they are on.
My initial array looks like this:
Array
(
[0] => Array
(
[userid] => 1301
[holes] => 6
[points] => -2
)
[1] => Array
(
[userid] => 231
[holes] => 5
[points] => 7
)
[2] => Array
(
[userid] => 3421
[holes] => 6
[points] => 7
)
[3] => Array
(
[userid] => 46
[holes] => 6
[points] => 3
)
[4] => Array
(
[userid] => 745
[holes] => 4
[points] => 7
)
)
Now, then I do this to order the array by points:
$sortArray = array();
foreach($playersArray as $person){
foreach($person as $key=>$value){
if(!isset($sortArray[$key])){
$sortArray[$key] = array();
}
$sortArray[$key][] = $value;
}
}
$orderby = "points";
array_multisort($sortArray[$orderby],SORT_ASC,$playersArray);
This orders the array by points, but as you can see, I have 3 players with 7 points but on different holes and would like to order those with same holes so the highest rank is the one on the lowest hole.
Hope this makes sense and any help is appreciated.
Thanks in advance :-)

Use usort.
Example:
usort($playersArray, function ($a, $b) {
if ($a['points'] == $b['points']) {
return $a['holes'] < $b['holes'];
}
return $a['points'] < $b['points'];
});
Change < to > to change sorting order.

Use usort.
This function will sort an array by its values using a user-supplied comparison function. If the array you wish to sort needs to be sorted by some non-trivial criteria, you should use this function.
usort($score, function ($a, $b) {
return $a['points'] - $b['points']
? $a['points'] - $b['points']
: $a['holes'] - $b['holes'];
});

Try this way :
function order_by_points($a, $b){
if ($a['points'] == $b['points'])
// sort the higher points first:
return $a['points'] < $b['points'] ? 1 : -1;
}

Related

PHP usort Multi-dimensional array

I'm having trouble getting usort to work and not sure what I'm missing. Below is an example of my array. I want to sort the array based on the value of the sort key.
Array
(
[0] => Array
(
[sort] => 1520546956
[row] => Data lives here
)
[1] => Array
(
[sort] => 1521047928
[row] => Data lives here
)
[2] => Array
(
[sort] => 1520525366
[row] => Data lives here
)
[3] => Array
(
[sort] => 1520525227
[row] => Data lives here
)
My code to try and sort this is:
foreach ($resultsArray as $record)
{
usort($record['sort'], function($a, $b)
{
if ($a == $b)
{
return 0;
}
return ($a < $b) ? -1 : 1;
});
}
However my code seems to be ineffective as the order of the array isn't changing. I feel like I'm close but can't identify what I'm missing. Thank you for any help!
A different approach to accomplish the same functionality is to use array_multisort with the desired combination of sorting flags.
Dataset:
$resultsArray = array(
array('sort'=>1520546956, 'row'=>'row 0 data'),
array('sort'=>1521047928, 'row'=>'row 1 data'),
array('sort'=>1520525366, 'row'=>'row 2 data'),
array('sort'=>1520525227, 'row'=>'row 3 data')
);
array_multisort Example:
$sortValues = array_column($resultsArray, 'sort');
array_multisort($sortValues, SORT_ASC, $resultsArray);
print_r($resultsArray);
Results: https://3v4l.org/NpVIc
Array
(
[0] => Array
(
[sort] => 1520525227
[row] => row 3 data
)
[1] => Array
(
[sort] => 1520525366
[row] => row 2 data
)
[2] => Array
(
[sort] => 1520546956
[row] => row 0 data
)
[3] => Array
(
[sort] => 1521047928
[row] => row 1 data
)
)
Alternatively you can still use usort, but in your function, you need to retrieve the associated array key named sort in order to compare the values.
usort Example:
usort($resultsArray, function($a, $b) {
if ($a['sort'] == $b['sort']) {
return 0;
}
return ($a['sort'] < $b['sort'] ? -1 : 1);
});
print_r($resultsArray);
Results: https://3v4l.org/5nfbc
Modified code to reflect the below as suggested:
usort($resultsArray, function($a, $b) { /* compare $a['sort'] and $b['sort'] */ }
Working perfectly.
$record['sort'] would have to be an array for that to work. Yet still, it does nothing.
I'm pretty sure you want to do this:
<?php
$multiArray = array(
array('sort'=>1520546956, 'row'=>'row 0 data'),
array('sort'=>1521047928, 'row'=>'row 1 data'),
array('sort'=>1520525366, 'row'=>'row 2 data'),
array('sort'=>1520525227, 'row'=>'row 3 data'));
foreach($multiArray as $a){
$numArray[] = $a['sort'];
}
asort($numArray, SORT_NUMERIC);
foreach($numArray as $k => $v){
$resArray[] = $multiArray[$k];
}
print_r($resArray);
?>
It is because php foreach construct works on the copy of the array provided(ie: $resultsArray), where php usort() function references or points to the same array. That is why your code is not working as expected.
If you don't understand this concept I suggest you a good online course by Kevin skoglund (php essential training) in Lynda.com

Sort Multi-dimensional Array by given indexes - PHP?

I have two array $days_order and $mysql_result, I want to sort $mysql_result array using $days_order array. I want to display MySQL result in days order ascending? Is there any way to do this or any other way so that I can pass $days_order in MySQL query in OrderBy section?
$days_order = Array([0] => 2[1] => 3[2] => 4[3] => 5 [4] => 6[5] => 7[6] => 1);
$mysql_result = Array (
[0] => Array
(
[hashtag] => a7e87329b5eab8578f4f1098a152d6f4
[title] => Flower
[day] => 3
)
[1] => Array
(
[hashtag] => b24ce0cd392a5b0b8dedc66c25213594
[title] => Free
[day] => 2
)
[2] => Array
(
[hashtag] => e7d31fc0602fb2ede144d18cdffd816b
[title] => Ready
[day] => 1
)
)
I want sorted array in $days_order
Output:
Array
(
[0] => Array
(
[hashtag] => b24ce0cd392a5b0b8dedc66c25213594
[title] => Free
[day] => 2
)
[1] => Array
(
[hashtag] => a7e87329b5eab8578f4f1098a152d6f4
[title] => Flower
[day] => 3
)
[2] => Array
(
[hashtag] => e7d31fc0602fb2ede144d18cdffd816b
[title] => Ready
[day] => 1
)
)
Use usort with a custom compare function.
Something like:
usort($ranked, function($a, $b) {
if ($a['day'] === $b['day']) return 0;
return ($a['day'] > $b['day']) ? -1 : 1;
});
You can read more about this function here.
I did this using following script:
function sort_array_custom_compare($mysql_result,$days_order)
{
uasort($mysql_result, function($a,$b) use ($days_order){
foreach($days_order as $value){
if($a['day'] == $value){
return 0;
break;
}
if($b['day'] == $value){
return 1;
break;
}
}
});
return $mysql_result;
}
You can use the custom order array in the comparison function of usort like this:
usort($mysql_result, function ($a, $b) use ($days_order) {
// Then check the position of the 'day' value of each element
// against the position of that value in $days_order.
$a = array_search($a['day'], $days_order);
$b = array_search($b['day'], $days_order);
if ($a < $b) return -1;
if ($a == $b) return 0;
return 1;
});
If you want to do it in MySQL, for just shifting the days forward like this you could use
ORDER BY (`day` + 1) % 7
Or if it needs to be more complex than just shifting a day you can use CASE to provide a specific order (although this CASE just does the same thing):
ORDER BY
CASE
WHEN `day` = 2 THEN 0
WHEN `day` = 3 THEN 1
WHEN `day` = 4 THEN 2
WHEN `day` = 5 THEN 3
WHEN `day` = 6 THEN 4
WHEN `day` = 7 THEN 5
WHEN `day` = 1 THEN 6
END;

How to sort nested PHP array

Can anyone tell me how to sort an array by key?
I want to sort this array by price.
this is my input array format
Array
(
[0] => Array
(
[house_data] => Array
(
[id] => 532
[max_person] => 8
[max_bedrooms] => 4
)
[image] => uploads/123.jpg
[price] => 1950
)
[1] => Array
(
[house_data] => Array
(
[id] => 531
[max_person] => 8
[max_bedrooms] => 5
)
[image] => uploads/1234.jpg
[price] => 1495
)
}
Try usort (http://php.net/manual/en/function.usort.php)
You should have something like:
function cmp($a, $b)
{
if ($a['price'] == $b['price']) {
return 0;
}
return ($a['price'] < $b['price']) ? -1 : 1;
}
usort($table, "cmp");
For making it one dimensional use serialize($array) function , it goes like this :$a = array() ; //your multidimensional array$b = array(); //output arrayforeach ($a as $key=>$value){ $b[] = serialize($value);}echo $b ;
Use the array_multisort() function for multidimensional array sorting.

Sort multidimensional array who has index

I got an array like that
Array
(
[0] => Array
(
[UnitESN] => 14296
[ScanNo] => 1
[ScanDate] => Nov 21
[ScanTime] => 10:15 AM
[Qualifiers] =>
[Notes] =>
[BadgeData] => Array
(
[0] => HEATH---
[1] => MCCU----
[2] => HER---
[3] => HCONNORS#------
[4] =>
[5] => 393
[6] => 13350
[7] =>
[8] =>
[9] => 111
)
[Signal] => +00/000
[ConnectionDelay] => 0407
)
[1] => Array
And so on... I want to order ASC or DESC... let's say on Col 8 and Col 8 is entry number 7 (8-1 because it start at zero) in BadgeData, any ideas ? I've try array_multisort but without succes.
Thanks
I'm glad you figured it out. Here's what I started writing before I got interrupted.
Basic uasort Example:
<?php
function cmp($a, $b) {
if ($a['BadgeData'][7] == $b['BadgeData'][7]) {
return 0;
}
// Ascending
return ($a['BadgeData'][7] < $b['BadgeData'][7]) ? -1 : 1;
}
// Order the values of the array based on the value in BadgeData[7] in ascending order..
uasort($array, 'cmp');
It looks like I may have misunderstood your original question though as I thought you wanted to sort the array by the value in BadgeData[7] but it seems like you wanted to sort the BadgeData for each array value.
Thanks to #Francois Deschenes to lead me on the right answer. Here's what I found :
http://ca2.php.net/manual/en/function.uasort.php#104714
I edited to fit my need. Thanks !
function SortArrayByCol(array $Array, $Key, $ASC=true, $Col=0) {
$Result = array();
$Values = array();
foreach($Array as $ID => $Value){
$Values[$ID] = isset($Value[$Key][$Col]) ? $Value[$Key][$Col] : null;
}
if($ASC){
asort($Values);
} else {
arsort($Values);
}
foreach($Values as $Key => $Value) {
$Result[$Key] = $Array[$Key];
}
return $Result;
}

help sorting this array

So I am looking to sort the multi dimensional array below by "fk_page_id" ascending. Does anyone have any pointers. I think usort() is where I have to look but it seems like I cant find anyone with my specific array structure.
Array
(
[0] => Array
(
[title] => subpage of subpage!
[id] => 5
[long_title] =>
[fk_page_id] => 4
)
[1] => Array
(
[title] => about us subpage
[id] => 4
[long_title] =>
[fk_page_id] => 2
)
[2] => Array
(
[title] => about us
[id] => 2
[long_title] =>
[fk_page_id] => 1
)
)
function cmp($a, $b) {
if($a['fk_page_id'] == $b['fk_page_id']) {
return 0;
} else {
return $a['fk_page_id'] < $b['fk_page_id'] ? -1 : 1;
}
}
usort($yourarray, 'cmp');
if you're using PHP 5.3+:
define(ASC,1);
define(DESC,-1);
function colsort($array,$col,$order=ASC) {
usort(
$array,
function($a,$b) use($col,$order) {
return strcmp($a[$col],$b[$col])*$order;
}
);
return $array;
}
colsort($x,'fk_page_id');

Categories