问题描述
@H_404_0@我有一个关联数组:
Array(
[110] => Array
(
[releaseDate] => 2020-08-15 00:00:00
[isNewest] =>
)
[128] => Array
(
[releaseDate] => 2020-08-01 00:00:00
[isNewest] =>
)
[129] => Array
(
[releaseDate] => 2020-08-01 00:00:00
[isNewest] =>
)
[130] => Array
(
[releaseDate] => 2020-08-01 00:00:00
[isNewest] =>
)
[132] => Array
(
[releaseDate] => 2020-08-01 00:00:00
[isNewest] =>
)
[123] => Array
(
[releaseDate] => 2020-07-01 00:00:00
[isNewest] =>
)
[124] => Array
(
[releaseDate] => 2020-07-01 00:00:00
[isNewest] =>
)
[125] => Array
(
[releaseDate] => 2020-07-01 00:00:00
[isNewest] =>
)
[127] => Array
(
[releaseDate] => 2020-07-01 00:00:00
[isNewest] =>
)
)
@H_404_0@通常应按releaseDate
进行排序,但isNewest
正确的元素应该排在首位。
@H_404_0@我使用uasort()
完成此操作:
uasort($arr,function($a,$b){
return $a['isNewest'] - $b['isNewest'];
});
@H_404_0@有时候isNewest
是正确的,但是在此示例中(在我第一次发现此错误的数据条件下),isNewest
对于所有条目都是false
。
@H_404_0@运行以上操作,结果如下:
Array
(
[124] => Array
(
[releaseDate] => 2020-07-01 00:00:00
[isNewest] =>
)
[125] => Array
(
[releaseDate] => 2020-07-01 00:00:00
[isNewest] =>
)
[127] => Array
(
[releaseDate] => 2020-07-01 00:00:00
[isNewest] =>
)
[123] => Array
(
[releaseDate] => 2020-07-01 00:00:00
[isNewest] =>
)
[132] => Array
(
[releaseDate] => 2020-08-01 00:00:00
[isNewest] =>
)
[128] => Array
(
[releaseDate] => 2020-08-01 00:00:00
[isNewest] =>
)
[129] => Array
(
[releaseDate] => 2020-08-01 00:00:00
[isNewest] =>
)
[130] => Array
(
[releaseDate] => 2020-08-01 00:00:00
[isNewest] =>
)
[110] => Array
(
[releaseDate] => 2020-08-15 00:00:00
[isNewest] =>
)
)
@H_404_0@问题在于,使用uasort()
的方式对数组进行排序似乎颠倒了数组的顺序。如果您查看以上两个数组并检查releaseDate
,您会明白我的意思。
@H_404_0@如果isNewest
对于任何条目都是正确的,则它们将排在第一位,但是其余的数组顺序仍将最终被颠倒。
@H_404_0@我似乎在理解uasort()
比较功能如何工作时遇到了一些麻烦。我尝试返回-1
和1
,甚至翻转了$a
和$b
参数,但无济于事。
@H_404_0@我在这里做错了什么?我如何在这里正确使用uasort()
,以使数组仍然按releaseDate
降序排列,但以这样的方式来处理:将isNewest
设置为true
的条目首先?
@H_404_0@谢谢!
解决方法
您可以使用单个uasort
调用对数据进行排序,首先检查日期是否相等(如果不相等,则返回该排序结果),然后首先对true
值进行排序:
uasort($array,function ($a,$b) {
// if dates not equal,return result of comparison
// since dates are in Y-m-d H:i:s format we can compare as strings
if (($rdcmp = strcmp($a['releaseDate'],$b['releaseDate'])) != 0) return $rdcmp;
// dates are equal,so sort true values first
if ($a['isNewest'] && !$b['isNewest']) return -1;
elseif (!$a['isNewest'] && $b['isNewest']) return 1;
else return 0;
});
print_r($array);
或者要对true
之前的所有false
值进行排序,然后按releaseDate
进行排序,可以使用以下代码:
uasort($array,$b) {
// sort true values first
if ($a['isNewest'] && !$b['isNewest']) return -1;
elseif (!$a['isNewest'] && $b['isNewest']) return 1;
// boolean values are equal,so sort by date.
// Since dates are in Y-m-d H:i:s format,we can sort as strings
else return strcmp($a['releaseDate'],$b['releaseDate']);
});
请注意,如果您想按releaseDate
降序进行排序,则应该更改
strcmp($a['releaseDate'],$b['releaseDate'])
到
strcmp($b['releaseDate'],$a['releaseDate'])
还请注意,如果您的布尔值实际上是true
和false
,则可以简化布尔值比较
return $b['isNewest'] - $a['isNewest'];
否则,由于PHP将所有类型的值都视为true
(包括负数,可能会因减法而使排序混乱),因此像在代码块中所做的那样,进行特定比较会更安全。 / p>
当每个isNewest
设置为false
时,我无法reproduce进行反转。
要获得所需的第一(isNewest
)和第二(releaseDate
)排序结果,可以简单地两次使用uasort
-最后使用最高优先级排序。
uasort($input,fn($a,$b) => strtotime($b['releaseDate']) - strtotime($a['releaseDate']));
uasort($input,$b) => $b['isNewest'] - $a['isNewest']);
工作example。
如果您不需要按键,也可以使用array_multisort。 (数字键将会丢失)。
array_multisort(
array_column($input,'isNewest'),SORT_DESC,// 1 before 0 (true before false)
array_column($input,'releaseDate'),$input
);
工作example。
提示未来。使用var_export在此处发布数据。因此,我们只需复制/粘贴它即可在代码中使用它。
如果您想在每个子组(isRelease=true
)中将releaseDate
个候选人放在首位,请翻转uasort
或{{ 1}}。