简体   繁体   English

自然排序scandir的结果?

[英]Naturally sorting results of a scandir?

I'm trying to sort an array containing the results of a scandir function. 我正在尝试对包含scandir函数结果的数组进行排序。 I've tried using the natsort() php function, but it doesn't appear to be working as I need it to for my directories. 我试过使用natsort()php函数,但是它似乎无法正常工作,因为我需要将其用于目录。

The contents of the scanned directory assume a HH(Z)DDMonYYYY naming convention. 扫描目录的内容采用HH(Z)DDMonYYYY命名约定。 After using the natsort function on the array, the result is this: 在数组上使用natsort函数后,结果是这样的:

$dates = ["21Z23Oct2017", "20Z23Oct2017", "19Z23Oct2017", 
          "19Z18Oct2017", "19Z17Oct2017", "19Z16Oct2017",
          "18Z23Oct2017", "18Z18Oct2017", "17Z23Oct2017", ...]

As you can see, the function is evaluating the first two digits and using them to sort, but it ignores the days (23, 18, 17, 16) in each name. 如您所见,该函数正在评估前两位数字并使用它们进行排序,但是它忽略了每个名称中的天数(23、18、17、16)。

I would like for the resulting array to look like this: 我希望结果数组看起来像这样:

$dates = ["21Z23Oct2017", "20Z23Oct2017", "19Z23Oct2017", 
          "18Z23Oct2017", "17Z23Oct2017", ...,
          "19Z18Oct2017", "18Z18Oct2017", "19Z17Oct2017", "19Z16Oct2017"]

Since the directories are created sequentially, I realize that I could sort by directory creation or modification time and be just fine 99% of the time. 由于目录是按顺序创建的,因此我意识到我可以按目录创建或修改时间进行排序,并且99%的时间都可以。 However, on rare occasions the directories modification times will not be in perfect order, and I'd like to avoid problems when that is the case. 但是,在极少数情况下,目录修改时间并不是很完美,因此我想避免出现这种情况。

Is there a way to accomplish my goal in php without having to use modification or creation times? 有没有一种方法可以实现我的目标,而无需使用修改或创建时间?

Thanks to all in advance! 预先感谢所有人!

EDIT : for context, I'm using a Python script to write to and perform a simple operation on each of these directories. 编辑 :对于上下文,我正在使用Python脚本写入这些目录并在其中执行简单的操作。 Python includes a package called "natsorted" for those unaware, which sorts the directories in the example array above without any trouble. Python为那些不知道的人提供了一个名为“ natsorted”的程序包,该程序对上面示例数组中的目录进行排序没有任何麻烦。 Just wondering if there was a simple php solution as well before I start adding complexity. 在我开始增加复杂性之前,只是想知道是否有一个简单的php解决方案。

All that natsort() does is try to address the sorting of strings with arbitrary-length digit sequences, it does not magically interpret bizarre date formats. natsort()所做的只是尝试解决具有任意长度数字序列的字符串的排序问题,它并不能神奇地解释奇异的日期格式。 Even the PHP functions that do try to figure out dates would not be able to figure this one out as they actually just use a predefined list of common formats and even then are problematic. 甚至确实尝试确定日期的PHP函数也无法解决这一问题,因为它们实际上仅使用预定义的常用格式列表,即使这样也存在问题。

IMHO you should always use something like DateTime::createFromFormat() and an explicit format string. 恕我直言,您应该始终使用类似DateTime::createFromFormat()和显式格式字符串。

<?php

$dates = ["21Z23Oct2017", "20Z23Oct2017", "19Z23Oct2017", 
          "19Z18Oct2017", "19Z17Oct2017", "19Z16Oct2017",
          "18Z23Oct2017", "18Z18Oct2017", "17Z23Oct2017"];

usort(
    $dates,
    function($a,$b){
        return DateTime::createFromFormat("H\ZdMY",$a) <=> DateTime::createFromFormat("H\ZdMY",$b);
    }
);

echo json_encode($dates, JSON_PRETTY_PRINT);

Output: 输出:

[
    "19Z16Oct2017",
    "19Z17Oct2017",
    "18Z18Oct2017",
    "19Z18Oct2017",
    "17Z23Oct2017",
    "18Z23Oct2017",
    "19Z23Oct2017",
    "20Z23Oct2017",
    "21Z23Oct2017"
]

This will work adequately for small sets of dates and/or when called infrequently. 这对于少量日期和/或不经常调用时将足够有效。 However if you're sorting a large number of dates, or sorting them frequently, you're going to want to pre-create the DateTime objects beforehand. 但是,如果要对大量日期进行排序或经常对它们进行排序,则需要预先创建DateTime对象。 As it stands both DateTimes in the comparison are recreated for each comparison . 按照目前的情况, 将为每个比较重新创建比较中的两个DateTime。

Going forward, you should always format dates in a readable and sortable fashion, eg: YYYY-MM-DD hh:mm:ss , ideally ISO8601 . 展望未来,您应该始终以可读且可排序的方式设置日期格式,例如: YYYY-MM-DD hh:mm:ss ,最好是ISO8601

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM