[英]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.