【问题标题】:PHP sort array keys by alphabetically and then numericallyPHP按字母顺序然后按数字对数组键进行排序
【发布时间】:2019-01-26 19:49:44
【问题描述】:

我正在尝试按键对数组(包含字母键和数字键)进行排序,其中字母键首先按字母顺序排列,然后数字键按数字排列。

用所有可用的标志尝试了ksort,但这并没有帮助。尝试了几个 SO 答案,但没有一个符合我的目的。这是我拥有的数组的一个示例..

$array = array(
    'Bat' => array(),
    'Dog' => array(),
    'Apple' => array(),
    'Cat' => array(),
    1 => array(),
    3 => array(),
    2 => array(),
    4 => array()
);  

我需要这样排序:

$array = array(
    'Apple' => array(),
    'Bat' => array(),
    'Cat' => array(),
    'Dog' => array(),
    0 => array(),
    1 => array(),
    2 => array(),
    3 => array()
);  

我从 SO 答案中了解到,它可能需要一个自定义函数来使用 usort 函数进行排序。这就是我迷路的地方。任何帮助或指导正确方向将不胜感激。

谢谢

【问题讨论】:

标签: php arrays sorting usort ksort


【解决方案1】:

如果你只使用英文字母和数字,通常的 ksort 函数可以正常工作

ksort($array);
print_r($array);

demo

【讨论】:

  • 奇怪。 ksort 在我测试时首先返回数字键。还是谢谢。
  • 哈!希望在我费心写出如此全面的答案(效率较低/直接的sn-p)之前,我会阅读您的答案。哦,好吧,其中有一些有价值的见解,未来的研究人员可能会发现有帮助。任何线索为什么 OP 的输入数组不遵守 ksort()
  • @Abhik 这实际上不会在您的项目中提供所需的结果吗?我们能否看到更真实的项目数据表示?你用的是什么php版本?
  • @mickmackusa 我看到两个变种:问题 XY 或在实际项目中使用非英文字母。
  • @mickmackusa 我正在使用 PHP7.2。 ksort 实际上是按字母和数字对数组进行排序。但是,我首先需要字母键,然后是数字键。 ksort 则完全相反,它先返回数字键,然后返回字母键。
【解决方案2】:

请不要介意这个问题。我已经使用自定义函数管理了实现 bu。如果有人遇到此问题,我将在此处发布答案以提供帮助。

function ev_sort_array( $array ) {
    $alp = array();
    $num = array();
    foreach ( $array as $key => $value ) {
        if ( is_numeric($key) ) {
            $num[$key] = $value;
        } else {
            $alp[$key] = $value;
        }
    }
    ksort( $alp );
    ksort( $num );

    return array_merge( $alp, $num );
}  

谢谢

【讨论】:

    【解决方案3】:

    你可以这样使用 uksort:

    $array = array(
    'Bat' => array(),
    'Dog' => array(),
    'Apple' => array(),
    'Cat' => array(),
    1 => array(),
    3 => array(),
    2 => array(),
    4 => array()
    ); 
    uksort($array,function($a,$b){
        if(is_int($a)&&is_int($b)) return $a-$b;
        if(is_int($a)&&!is_int($b)) return 1;
        if(!is_int($a)&&is_int($b)) return -1;
        return strnatcasecmp($a,$b);
    });
    print_r($array);
    

    输出如预期:

    Array
    (
        [Apple] => Array
            (
            )
    
        [Bat] => Array
            (
            )
    
        [Cat] => Array
            (
            )
    
        [Dog] => Array
            (
            )
    
        [1] => Array
            (
            )
    
        [2] => Array
            (
            )
    
        [3] => Array
            (
            )
    
        [4] => Array
            (
            )
    
    )
    

    【讨论】:

      【解决方案4】:

      正如@splash58 所说,ksort() 就是必需的。

      也就是说,如果您的项目数据按字母顺序排列数字数据,并且您需要颠倒这些组的顺序...

      uksort() 是这项工作最直接/最合适的功能。

      *仔细选择你的关键评估函数:

      • is_numeric()true 有广泛的定义——请参阅手册。
      • is_int()(及其别名is_integer())在检查数据类型时非常严格。重要的是,像"1" 这样的字符串键将评估为false
      • ctype_digit() 虽然要求所有字符都是数字,但不适用于非字符串类型的值。重要的是,像 8 这样的非字符串键将评估为 false

      如果你使用的是php7,你可以很好地使用spaceship operator<=>)。如果你的 php 版本低于 7,你可以使用任何你喜欢的 old-skool 比较。

      我的解决方案允许飞船操作​​员在整数之前排序非整数,然后对这些值进行 ASC 排序。

      代码:(Demo)

      $array = [
          2 => [],
          'Bat' => [],
          'Dog' => [],
          12 => [],
          'être' => [],
          'Cat' => [],
          1 => [],
          3 => [],
          'Apple' => [],
          4 => []
      ];
      
      uksort($array, function ($a, $b) {
          return [is_int($a), $a] <=> [is_int($b), $b];
      });
      
      var_export($array);
      

      is_int() 调用将返回 truefalse。它们分别被比较为10。由于 ASC 排序,这意味着 false 评估将在 true 评估之前。

      输出:(与ksort()完全相同)

      【讨论】:

      • 你可以做return $b &lt;=&gt; $a;,因为任何“not-dogit”字符串都小于任何数字?
      • 嗯。我想我的范围没有超出样本数据。没想到这么远。
      猜你喜欢
      • 2021-12-28
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多