【问题标题】:Sorting of multidimensional array with with numbers and letters用数字和字母对多维数组进行排序
【发布时间】:2017-03-08 16:16:40
【问题描述】:

如何对多维数组进行排序。这就是我的数组的样子

[0] => Array
    (
      [id] => 1
      [title] => 3A
      [active] => 1
    )
[1] => Array
    (
      [id] => 1
      [title] => A
      [active] => 1
    )
[2] => Array
    (
      [id] => 1
      [title] => 2A
      [active] => 1
    )
[3] => Array
    (
      [id] => 1
      [title] => B
      [active] => 1
    )

我尝试了几种 usort 方法,但似乎无法使其正常工作。我需要对数组进行排序,以便它按数字排序,然后按字母数字排序,如下所示:A、B、2A、3A。 我不确定如果不添加位置字段来规定标题的顺序是否可行,或者我在这里遗漏了什么?

【问题讨论】:

  • 你排序不清楚。您想按数字 ASC 排序,然后按字母数字 ASC 排序?您的结果将是 2A、3A、A、B 等等。

标签: php arrays sorting multidimensional-array


【解决方案1】:

您可以为每个数字部分在左侧用0填充的项目构建一个“键”,这样排序函数就可以进行简单的字符串比较:

$temp = [];

foreach ($arr as $v) {
    $key = sscanf($v['title'], '%d%s');
    if (empty($key[0])) $key = [ 0, $v['title'] ];
    $key = vsprintf("%06d%s", $key);
    $temp[$key] = $v;
}

ksort($temp);

$result = array_values($temp);

demo

这种技术称为“Schwartzian Transform”。

【讨论】:

    【解决方案2】:

    正如@Kargfen 所说,您可以将 usort 与您的自定义函数一起使用。喜欢这个:

    usort($array, function(array $itemA, array $itemB) {
       return myCustomCmp($itemA['title'], $itemB['title']);
    }); 
    
    function myCustomCmp($titleA, $titleB) {
        $firstLetterA = substr($titleA, 0, 1);
        $firstLetterB = substr($titleB, 0, 1);
    
        //Compare letter with letter or number with number -> use classic sort
        if((is_numeric($firstLetterA) && is_numeric($firstLetterB)) || 
        (!is_numeric($firstLetterA) && !is_numeric($firstLetterB)) ||
        ($firstLetterA === $firstLetterB)
        ) {
            return strcmp($firstLetterA, $firstLetterB);
        }
    
        //Letters first, numbers after
        if(! is_numeric($firstLetterA)) {
            return -1;
        }
    
        return 1;
    }
    

    这个比较功能只是基于你的标题的第一个字母,但它可以完成这项工作;-)

    【讨论】:

      【解决方案3】:

      您可以借助 usort 和自定义回调来解决该问题:

      function customSort($a, $b)
      {
          if ($a['id'] == $b['id']) {
              //if there is no number at the beginning of the title, I add '1' to temporary variable
              $aTitle = is_numeric($a['title'][0]) ? $a['title'] : ('1' . $a['title']);
              $bTitle = is_numeric($b['title'][0]) ? $b['title'] : ('1' . $b['title']);
      
              if ($aTitle != $bTitle) {
                  return ($aTitle < $bTitle) ? -1 : 1;
              }
              return 0;
          }
          return ($a['id'] < $b['id']) ? -1 : 1;
      }
      
      usort($array, "customSort");
      

      函数首先比较“id”值,然后如果两个项目相等,它会检查“title”值。

      【讨论】:

        猜你喜欢
        • 2021-07-31
        • 2011-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-09
        • 1970-01-01
        相关资源
        最近更新 更多