按第二级键降序对多维数组进行排序,然后按日历顺序对第三级键(月份名称)进行排序

问题描述 投票:0回答:2

我有很多文件夹,我使用

DirectoryIterator
将它们放入多维数组中。结果是这样的

array:10 [▼
  "SomeTitle" => array:2 [▼
    2018 => array:3 [▼
      "February" => array:4 [▶]
      "January" => array:1 [▶]
      "March" => array:1 [▶]
    ]
    2017 => array:11 [▼
      "February" => array:9 [▶]
      "January" => array:12 [▶]
      "March" => array:9 [▶]
      "September" => array:9 [▶]
      "June" => array:8 [▶]
      "December" => array:12 [▶]
      "October" => array:8 [▶]
      "July" => array:10 [▶]
      "April" => array:8 [▶]
      "August" => array:10 [▶]
      "May" => array:10 [▶]
    ]
  ]
]

所以我有主键,然后是年份,然后是月份,然后是其他一些数据。

我想做的是按年份和月份组织数据。 所以2018年应该永远是第一位的。 然后我需要按月份顺序组织月份。 目前,我正在将数组传递给这个函数

function sortArray($arr) {
    ksort($arr);

    foreach ($arr as $k => $v) {
        if (is_array($v)) {
            $arr[$k] = $this->sortArray($v);
        }
    }
    return $arr;
}

我认为我不需要 ksort,因为这似乎把 2017 年放在第一位。 当我运行上面的代码时,我得到以下结果

array:10 [▼
  "SomeTitle" => array:2 [▼
    2017 => array:11 [▼
      "April" => array:8 [▶]
      "August" => array:10 [▶]
      "December" => array:12 [▶]
      "February" => array:9 [▶]
      "January" => array:12 [▶]
      "July" => array:10 [▶]
      "June" => array:8 [▶]
      "March" => array:9 [▶]
      "May" => array:10 [▶]
      "October" => array:8 [▶]
      "September" => array:9 [▶]
    ]
    2018 => array:3 [▼
      "February" => array:4 [▶]
      "January" => array:1 [▶]
      "March" => array:1 [▶]
    ]
  ]
]

所以一切基本上都是按字母顺序排列的。 有什么方法可以改变这一点,以便年份从最新到最旧开始,并且月份按日历顺序排列?

php arrays sorting
2个回答
2
投票

与月份相对应的数字键更有意义,但要使用名称来实现:

function sortArray($arr) {
    krsort($arr);

    foreach ($arr as $k => &$v) {
        if (is_array($v)) {
            array_multisort(array_map(function($m) {
                                          return date('m', strtotime($m));
                                      }, array_keys($v)), $v);
        }
    }
    return $arr;
}

您希望

krsort
反向排序,然后映射数组 Months 以获取月份编号,并在此基础上对原始数组进行排序。 注意
&$v

你可以用这个代替

date
:

return strtotime($m);

1
投票

您可以使用

uksort()
手动检查:

  • 如果键是数值:自然排序
  • 如果键与
    strtotime()
    不匹配,则使用
    strcmp()
    排序(最好检查键是否等于“预定义”月份名称,而不是检查
    strtotime() === false
    。)
  • 否则使用
    strtotime()
  • 进行排序

代码:

function sortArray($arr) {
    uksort($arr, function($k1, $k2) {
        if (is_numeric($k1)) return $k1-$k2 ;
        if (strtotime($k1) === false) return strcmp($k1, $k2);
        return strtotime($k1) - strtotime($k2);
    });

    foreach ($arr as $k => $v) {
        if (is_array($v)) {
            $arr[$k] = $this->sortArray($v);
        }
    }
    return $arr;
}
$array = sortArray($array);
print_r($array);

输出:

Array (
  [SomeTitle] => Array (
    [2017] => Array (
      [January] => Array()
      [February] => Array()
      [March] => Array()
      [April] => Array()
      [May] => Array()
      [June] => Array()
      [July] => Array()
      [August] => Array()
      [September] => Array()
      [October] => Array()
      [December] => Array()
    )
    [2018] => Array (
      [January] => Array()
      [February] => Array()
      [March] => Array()
    )
  )
)

这是一个工作演示

© www.soinside.com 2019 - 2024. All rights reserved.