Sort Multi-dimensional Array by given indexes - PHP? - 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;

Related

Sort array with 2 conditions

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;
}

Comparing in an Array: If two highest value exists, then compare the other value

Suppose I have an array like:
array( [0] => array([item]=>apple [buy]=>50 [sell]=>30)
[1] => array([item]=>lemon [buy]=>50 [sell]=>60)
[2] => array([item]=>banana [buy]=>40 [sell]=>20)
[3] => array([item]=>orange [buy]=>20 [sell]=>30)
)
Currently I am using this script to check which item has the most buyer
function getMax($array, $val)
{
$max = 0;
foreach( $array as $k => $v )
{
$max = max( array( $max, $v[$val] ) );
}
return $max;
}
$highestBuy = getMax($thisArray, 'buy');
foreach($thisArray as $i=>element){
if($element['buy'] == $highestBuy){
$thisArray[$i]['highestBuy'] = 'yes';
} else {
$thisArray[$i]['highestBuy'] = 'no';
}
}
In this case, both apple and lemon will have highestBuy a yes value. But now I want to find out which item is the most popular by checking their sell if there are two or more same value of highestBuy. Which is the most simple or fastest way to make the output like:
array([0] => array([item]=>apple [buy]=>50 [sell]=>30 [mostPopular]=>no)
[1] => array([item]=>lemon [buy]=>50 [sell]=>60 [mostPopular]=>yes)
[2] => array([item]=>banana [buy]=>40 [sell]=>20 [mostPopular]=>no)
[3] => array([item]=>orange [buy]=>20 [sell]=>30 [mostPopular]=>no)
)
Thanks in advance.
EDIT:
What I want to do is:
find out the highest buy
If this value occur only once(which means there are one highest buy in the array) then push the [mostPouplar]=>yes into the array
If not(there are two or more same highest value), then find out the highest sell.
That's mean if the highest value is unique, it will stop doing further action. If not, it will keep going to find secondary highest value in an array. Is it possible to achieve this?
Sort array with your rules and take first element
$array = array( '0' => array('item'=>apple, 'buy'=>50 ,'sell'=>30),
'1' => array('item'=>lemon, 'buy'=>50, 'sell'=>60),
'2' => array('item'=>banana, 'buy'=>40, 'sell'=>20),
'3' => array('item'=>orange, 'buy'=>20 ,'sell'=>30)
);
usort($array,
function($a, $b) {
$res = $b['buy'] - $a['buy'];
if (!$res) $res = $b['sell'] - $a['sell'];
return $res; });
result:
Array (
[0] => Array ( [item] => lemon [buy] => 50 [sell] => 60 )
[1] => Array ( [item] => apple [buy] => 50 [sell] => 30 )
[2] => Array ( [item] => banana [buy] => 40 [sell] => 20 )
[3] => Array ( [item] => orange [buy] => 20 [sell] => 30 ) )
I had changed the getMax() to return the index of the most popular item
function getMax($array, $val, $val2)
{
$max_item = 0;
foreach( $array as $k => $v )
{
if($array[$max_item][$val] <= $v[$val] && $array[$max_item][$val2] <= $v[$val2])
$max_item = $k;
}
return $max_item;
}
$highestBuy = getMax($thisArray, 'buy', 'sell');
foreach($thisArray as $i => $element){
$thisArray[$i]['mostPopular'] = ($i == $highestBuy) ? 'yes' : 'no';
}

PHP select arrays based on value in a multidimensional array

I have an array with the below structure and I need to select the greatest education level from the sub arrays that have selected=>1, the greater the [key] the greater the education level.
anyway to do this with PHP built in array functions?
Array
(
[0] => Array
(
[key] => 0
[selected] => 1
[value] => Highschool diploma
)
[1] => Array
(
[key] => 1
[selected] => 0
[value] => Vocational training
)
[2] => Array
(
[key] => 2
[selected] => 0
[value] => College degree (Outside Quebec)
)
[3] => Array
(
[key] => 3
[selected] => 1
[value] => College degree (Quebec)
)
[4] => Array
(
[key] => 4
[selected] => 1
[value] => Baccalaureate
)
[5] => Array
(
[key] => 5
[selected] => 0
[value] => Masters degree
)
[6] => Array
(
[key] => 6
[selected] => 0
[value] => Doctorate
)
)
PHP >= 5.5.0
To get all the selected keys:
$keys = array_filter(array_column($array, 'selected'));
// or if there can be values other than 0 and 1
$keys = array_keys(array_column($array, 'selected'), '1');
To get the key with the highest value:
$max = max(array_filter(array_column($array, 'selected')));
// or if there can be values other than 0 and 1
$max = max(array_keys(array_column($array, 'selected'), '1'));
array_walk($data, function($el) use(&$ret) {
// or if (empty($ret) ...
if (!isset($ret) || ($el['selected'] >= 1 && $ret['key'] < $el['key']))
$ret = $el;
});
var_dump($ret);
Just do not forget to unset or set $ret = false; //null, etc..
if you want to run this code multiple times :)
If you want to use php built-ins, array_reduce is probably the way to go. Something like this should do the trick:
$result = array_reduce($theArray, function($state, $item) {
if($item['selected'] !== 1) return $state;
if($state === null) return $item;
if($item['key'] > $state['key']) return $item;
return $state;
});
echo $result['value'];
update: I should note that the above only works in PHP 5.3 or later, because it uses anonymous functions, which weren't available in earlier versions of PHP. If you're working with an earlier version, you really should upgrade. But if you can't upgrade, then you'll have to define the function part as a normal stand-alone function, and then pass the name of your function (as a string) in the second argument to array_reduce. This approach is shown in the examples on the doc page for array_reduce.
Sure. Loop through each inner array, and check their values against the one that is currently top. For example: https://eval.in/private/5c5a2ba8015119
$final = array();
foreach($array as $education) {
if($education['selected'] != 1) {
continue;
}
if(isset($final['key']) == FALSE
OR $education['key'] > $final['key']) {
$final = $education;
}
}
echo print_r($final, true);
I've build a test function for you.
Tested and working! Cheers to Baccalaureate!
<?php
// Demo Data
$your_array = array(
array(
'key'=>0,
'selected'=>1,
'value'=>'Highschool diploma'
),
array(
'key'=>1,
'selected'=>0,
'value'=>'Vocational training'
),
array(
'key'=>2,
'selected'=>0,
'value'=>'College degree (Outside Quebec)'
),
array(
'key'=>3,
'selected'=>1,
'value'=>'College degree (Quebec)'
),
array(
'key'=>4,
'selected'=>1,
'value'=>'Baccalaureate'
),
array(
'key'=>5,
'selected'=>0,
'value'=>'Masters degree'
),
array(
'key'=>6,
'selected'=>0,
'value'=>'Doctorate'
)
);
// Actual function
$array_count = (count($your_array)-1);
$highest_education = 'Nothing found.';
for($i=$array_count;$i>0;$i--)
{
if($your_array[$i]['selected']==1)
{
$highest_education = $your_array[$i]['value'];
break;
}
}
// Testing output
echo $highest_education;
?>

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.

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