Reputation: 16769
I have tried sorting the below array to keep the even values on top and in sorted order from asc
to desc
$array = array(1,2,3,4,5,6,7,8,9,10);
I tried this to sort the array
usort($array, function($a, $b) {
if ($a % 2 == 0 )
{
return 1 ;
}
else
{
return -1;
}
}
);
I got the output like below
Array
(
[0] => 7
[1] => 9
[2] => 1
[3] => 5
[4] => 3
[5] => 2
[6] => 4
[7] => 6
[8] => 8
[9] => 10
)
And I want the output array to be
Array
(
[0] => 2
[1] => 4
[2] => 6
[3] => 8
[4] => 10
[5] => 1
[6] => 3
[7] => 5
[8] => 7
[9] => 9
)
The even and odd values should be sorted in asc to desc order but keep the even values on top of odd values
Upvotes: 3
Views: 1741
Reputation: 41810
For the comparison function, first take the difference of the mod 2 values of the two numbers.
It will be -1, 0, or 1. If it's not zero, then one number is even and the other is odd, so you can return that value. (That will sort odds above evens.)
If it is zero, then either both numbers are even or both numbers are odd, and you need to take the difference of the two numbers to break the tie.
A concise way to write this is:
usort($array, function($a, $b) {
return $a % 2 - $b % 2 ?: $a - $b;
});
To sort odd numbers at the beginning instead, swap $a
and $b
in the first comparison.
return $b % 2 - $a % 2 ?: $a - $b;
Upvotes: 0
Reputation: 12860
Short and simple way to write it:
<?php
$array = array(1,2,3,4,5,6,7,8,9,10);
usort($array, function($a, $b){
if ($a % 2 == $b % 2) {
return $a - $b;
}
return $a % 2 != 0;
});
print_r($array);
?>
or with a ternary:
<?php
$array = array(1,2,3,4,5,6,7,8,9,10);
usort($array, function($a, $b){
return ($a % 2 == $b % 2) ? ($a - $b) : ($a % 2 != 0);
});
print_r($array);
?>
Upvotes: 1
Reputation: 9311
I think you need a somewhat more complex function. Because when you look at it there are different cases to take care of and in every one of them something different must happen:
$a
and $b
both are even: default numeric comparison$a
and $b
both are odd: default numeric comparison$a
is even, $b
is odd: $a
is always smaller than $b
$a
is odd, $b
is even: $b
is always smaller than $a
And for the implementation see the answer of fab.
Upvotes: 4
Reputation: 212412
usort($array, function($a, $b) {
if ($a % 2 == $b % 2) {
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
} elseif ($a % 2 == 0) {
return -1 ;
} else {
return 1;
}
}
);
Upvotes: 2
Reputation: 6000
A bit lenghty but works fine for me:
$array = array(1,2,3,4,5,6,7,8,9,10);
$even =array();
$odd = array();
foreach ($array as $item) {
if($item%2==0) {
$even[] = $item;
}
else {
$odd[] = $item;
}
}
usort($even);
usort($odd);
$array_sort = array_merge($even,$odd);
print_r($array_sort);
Upvotes: 2
Reputation: 24551
usort
is not stable. The documentation states:
If two members compare as equal, their relative order in the sorted array is undefined.
So, what you can do is:
usort($array, function($a, $b) {
if ($a % 2 == $b % 2) {
return intval($a - $b);
}
elseif ($a % 2 == 0 )
{
return -1 ;
}
else
{
return 1;
}
}
);
This compares the actual values if both are even or both are odd.
Upvotes: 7