php - PHP使用空值排序位置但保持结构
问题描述
我想用数据库中可能存在或不存在的值对数组进行排序,并且应该尊重顺序结构。
默认结构(位置从 1 到 5):
Amazon | Google | Ebay | Microsoft | Alibaba
这个结构在 PHP 中是这样初始化的:
$data =
[
'Amazon' => ['position' => null],
'Google' => ['position' => null],
'Ebay' => ['position' => null],
'Microsoft' => ['position' => null],
'Alibaba' => ['position' => null]
];
重要提示:存储在数据库中的位置总是等于或大于 1。
假设谷歌在数据库中排名第 1,阿里巴巴排名第 4:
$data['Google']['position'] = $fromDb->google->position; // 1
$data['Alibaba']['position'] = $fromDb->alibaba->position; // 4
如果我使用以下函数对数组进行排序array_multisort
:
$sort = [];
foreach ($data as $key => $value)
$sort[$key] = $value['position'];
array_multisort($sort, SORT_ASC, $data);
输出:
Array
(
[Amazon] =>
[Ebay] =>
[Microsoft] =>
[Google] => 1
[Alibaba] => 4
)
期望的输出:
Array
(
[Google] => 1
[Amazon] => 2
[Ebay] => 3
[Alibaba] => 4
[Microsoft] => 5
)
解决方案
在做一个简单的之前填写缺失值usort
:
$data = [
'Amazon' => ['position' => null],
'Google' => ['position' => 1],
'Ebay' => ['position' => null],
'Microsoft' => ['position' => null],
'Alibaba' => ['position' => 4]
];
// Find existing positions.
$positions = array_filter(array_column($data, 'position'));
$i = 1;
foreach ($data as &$comp) {
if ($comp['position']) {
// Element already has a position, skip to next one.
continue;
}
while (in_array($i, $positions)) {
// Increment the counter until we find a value not yet taken.
$i++;
}
// Assign the counter value to the current element.
$comp['position'] = $i++;
}
unset($comp);
// Sort all values with a simple comparison function.
uasort($data, function ($a, $b) { return $a['position'] <=> $b['position']; });
有点花哨:
// Compute the *missing* positions by subtracting the existing positions
// (extracted via array_column) from the set of possible positions
// (generated with range()).
$positions = array_diff(range(1, count($data)), array_filter(array_column($data, 'position')));
// Apply the missing positions to the array elements in order
// (taking positions off the beginning with array_shift).
array_walk($data, function (&$i) use (&$positions) {
if (!$i['position']) {
$i['position'] = array_shift($positions);
}
});
// Sort all values with a simple comparison function.
uasort($data, function ($a, $b) { return $a['position'] <=> $b['position']; });
推荐阅读
- vb.net - 处理来自另一个类的某些事件
- java - 找不到常见的超类 - Proguard
- intellij-idea - 在 IntelliJ IDEA 中的终端选项卡之间切换
- c# - 如何在 .NET Core 应用程序的 dll 被覆盖时停止关闭?
- angularjs - HTTP 状态 406 - 不可接受 Spring mvc
- mongodb - 这个 mongo 查询有什么问题?
- javascript - 如何在highcharts中获得相对于十字线的轴值
- raspbian - 在 Raspbian 上安装 GNU 收音机
- mysql - 如何解决实体框架打开 DataReader 问题
- java - where are the #list looped variables in Netbeans wizard freemarker