假设我有一个数组,例如:
[
['action' => 'Created', 'timestamp' => '2023-10-30 20:51:57.284602'],
['action' => 'Updated', 'timestamp' => '2023-10-30 20:51:57.284603'],
['action' => 'Started', 'timestamp' => '2023-10-30 20:51:57.284604'],
['action' => 'Bid placed', 'timestamp' => '2023-10-30 20:51:57.284605'],
['action' => 'Max bid placed', 'timestamp' => '2023-10-30 20:51:57.284606'],
['action' => 'Bid placed', 'timestamp' => '2023-10-30 20:51:57.284607'],
['action' => 'Max bid placed', 'timestamp' => '2023-10-30 20:51:57.284608'],
// and so on...
['action' => 'Ended', 'timestamp' => '2023-10-30 20:51:57.284609'],
],
我需要交换所有“出价”项目与“最高出价”项目的顺序。可能没有任何“最高出价”项目。数组中也可能有很多这样的条目。
例如
[
['action' => 'Created', 'timestamp' => '2023-10-30 20:51:57.284602'],
['action' => 'Updated', 'timestamp' => '2023-10-30 20:51:57.284603'],
['action' => 'Started', 'timestamp' => '2023-10-30 20:51:57.284604'],
['action' => 'Max bid placed', 'timestamp' => '2023-10-30 20:51:57.284606'],
['action' => 'Bid placed', 'timestamp' => '2023-10-30 20:51:57.284605'],
['action' => 'Max bid placed', 'timestamp' => '2023-10-30 20:51:57.284608'],
['action' => 'Bid placed', 'timestamp' => '2023-10-30 20:51:57.284607'],
// and so on...
['action' => 'Ended', 'timestamp' => '2023-10-30 20:51:57.284609'],
],
我已经尝试过一些事情,但似乎总是以以下顺序结束:
[
['action' => 'Created'],
['action' => 'Updated'],
['action' => 'Started'],
['action' => 'Max bid placed'],
['action' => 'Max bid placed'],
['action' => 'Bid placed'],
['action' => 'Bid placed'],
// and so on...
['action' => 'Ended'],
],
这真的可能吗?
迭代时,缓存给定组的起点。
如果已启动的组在遇到
Max bid placed
行之前遇到非组条目,则中止该组。
当一个组开始并以
Max bid placed
行适当结束时,删除 Max bid placed
行并在组中的第一行之前将其重新注入。该数组将通过 array_splice()
函数调用自动重新索引。后续行索引将不受每次操作的影响,因为在操作之前数组大小不会增加/减少。
代码:(演示)
$start = null;
foreach ($array as $i => $row) {
if ($row['action'] === 'Bid placed') {
$start ??= $i; // only store the first $i in the group
continue;
}
if ($start !== null && $row['action'] === 'Max bid placed') {
array_splice($array, $start, 0, array_splice($array, $i, 1)); // prune and reinsert row
}
$start = null;
}
var_export($array);
我最初考虑过,但放弃了以下方法,因为对于有条件移动数组中的单行这一相对简单的过程来说,它需要太多的排序和内存。
// DON'T USE THIS CODE, IT IS NOT CORRECT.
$grouper = [];
$actions = [];
$timestamps = [];
$i = 0;
foreach ($array as $row) {
$grouper[] = $i;
$actions[] = $row['action'];
$timestamps[] = $row['timestamp'];
$i += $row['action'] !== 'Bid placed';
}
array_multisort($grouper, $actions, SORT_DESC, $timestamps, $array);
var_export($array);