我想用数据库中可能存在或不存在的值对数组进行排序,并且应该尊重order结构。
结构(位置从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
)发布于 2020-02-28 15:13:39
在执行简单的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']; });发布于 2020-02-28 15:02:45
试着:
$sort = [];
$null_position = 1;
arsort($data);
foreach ($data as $key => $value){
while(in_array($null_position,array_column($data,'position'))) {
$null_position++;
}
$sort[$key] = $value['position'] ?? $null_position++;
}
asort($sort);而不是
$sort = [];
foreach ($data as $key => $value)
$sort[$key] = $value['position'];
array_multisort($sort, SORT_ASC, $data);发布于 2020-02-28 15:05:50
解决了问题。
不确定这是否是最好的方法,但输出是所需的。
// Create three arrays to save the positions being used, etc
$itemsWithoutPosition = [];
$itemsWithPosition = [];
$listOfPositionsUsed = [];
// First grab the positions used
foreach ($original as $key => $value)
{
if ($value['position'])
{
$itemsWithPosition[$key] = ['position' => $value['position']];
array_push($listOfPositionsUsed, $value['position']);
}
}
// Function to find the next available position
function findAvailablePosition($listOfPositionsUsed)
{
for ($i = 1; $i <= 5; $i++)
{
if (in_array($i, $listOfPositionsUsed))
continue;
return $i;
}
}
// Loop through the items that do not have position set
foreach ($original as $key => $value)
{
if (!$value['position'])
{
$position = findAvailablePosition($listOfPositionsUsed);
$itemsWithoutPosition[$key] = ['position' => $position];
array_push($listOfPositionsUsed, $position);
}
}
// Merge both results
$result = array_merge($itemsWithPosition, $itemsWithoutPosition);
// Sort the results
array_multisort($result, SORT_ASC);
// Voilá
Array
(
[Google] => Array
(
[position] => 1
)
[Amazon] => Array
(
[position] => 2
)
[Ebay] => Array
(
[position] => 3
)
[Alibaba] => Array
(
[position] => 4
)
[Microsoft] => Array
(
[position] => 5
)
)https://stackoverflow.com/questions/60454029
复制相似问题