3

我尝试对下面的数组进行排序以将偶数值保持在顶部并按从asc到的排序顺序desc

$array = array(1,2,3,4,5,6,7,8,9,10);

我试过这个对数组进行排序

usort($array, function($a, $b) { 
                    if ($a % 2 == 0 )
                    { 
                        return 1 ;
                    }
                    else 
                    { 
                        return -1;
                    }
            }
        );

我得到如下输出

Array
(
    [0] => 7
    [1] => 9
    [2] => 1
    [3] => 5
    [4] => 3
    [5] => 2
    [6] => 4
    [7] => 6
    [8] => 8
    [9] => 10
)

我希望输出数组是

Array
(
    [0] => 2
    [1] => 4
    [2] => 6
    [3] => 8
    [4] => 10
    [5] => 1
    [6] => 3
    [7] => 5
    [8] => 7
    [9] => 9
)

偶数和奇数应按升序到降序排序,但将偶数保持在奇数之上

4

6 回答 6

6

usort不稳定。_ 该文档指出:

如果两个成员比较相等,则它们在排序数组中的相对顺序是未定义的。

所以,你可以做的是:

usort($array, function($a, $b) {
                if ($a % 2 == $b % 2) {
                    return intval($a - $b);
                }
                elseif ($a % 2 == 0 )
                { 
                    return -1 ;
                }
                else 
                { 
                    return 1;
                }
        }
    );

如果两者都是偶数或两者都是奇数,则会比较实际值。

于 2013-02-08T07:43:45.453 回答
4

我认为您需要一个更复杂的功能。因为当您查看它时,需要处理不同的情况,并且在每种情况下都必须发生不同的事情:

  • $a两者$b都是偶数:默认数字比较
  • $a两者$b都是奇数:默认数字比较
  • $a是偶数,$b是奇数:$a总是小于$b
  • $a是奇数,$b是偶数:$b总是小于$a

对于实施,请参阅fab 的答案

于 2013-02-08T07:46:15.177 回答
2

有点长,但对我来说很好:

$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);
于 2013-02-08T07:44:00.017 回答
2
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;
                    }
            }
        );
于 2013-02-08T07:44:36.237 回答
1

简短而简单的编写方法:

<?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);
?>

或使用三元:

<?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);
?>
于 2013-02-08T08:00:41.093 回答
0

对于比较函数,首先取两个数的 mod 2 值的差。

它将是 -1、0 或 1。如果它不为零,则一个数字是偶数,另一个是奇数,因此您可以返回该值。(这将使赔率高于偶数。)

如果为零,则要么两个数字都是偶数,要么两个数字都是奇数,您需要取两个数字的差来打破平局。

一个简洁的写法是:

usort($array, function($a, $b) {
    return $a % 2 - $b % 2 ?: $a - $b;
});

要在开始时对奇数进行排序,请在第一次比较中交换$a和。$b

return $b % 2 - $a % 2 ?: $a - $b;
于 2018-11-01T21:21:21.750 回答