首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP排序位置为空值但维护结构

PHP排序位置为空值但维护结构
EN

Stack Overflow用户
提问于 2020-02-28 14:45:52
回答 4查看 69关注 0票数 2

我想用数据库中可能存在或不存在的值对数组进行排序,并且应该尊重order结构。

结构(位置从1到5):

代码语言:javascript
复制
Amazon | Google | Ebay | Microsoft | Alibaba

此结构是以PHP方式初始化的:

代码语言:javascript
复制
$data = 
[
    'Amazon'    => ['position' => null],
    'Google'    => ['position' => null],
    'Ebay'      => ['position' => null],
    'Microsoft' => ['position' => null],
    'Alibaba'   => ['position' => null]
];

重要:数据库中存储的位置总是等于或大于1。

让我们说,谷歌在数据库中占据了第1和阿里巴巴4的位置:

代码语言:javascript
复制
$data['Google']['position'] = $fromDb->google->position; // 1
$data['Alibaba']['position'] = $fromDb->alibaba->position; // 4

如果我使用array_multisort函数对数组进行排序,如下所示:

代码语言:javascript
复制
$sort = [];

foreach ($data as $key => $value)
    $sort[$key] = $value['position'];

array_multisort($sort, SORT_ASC, $data);

输出

代码语言:javascript
复制
Array
(
    [Amazon] => 
    [Ebay] => 
    [Microsoft] => 
    [Google] => 1
    [Alibaba] => 4
)

期望输出

代码语言:javascript
复制
Array
(
    [Google] => 1
    [Amazon] => 2
    [Ebay] => 3
    [Alibaba] => 4
    [Microsoft] => 5
)
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-02-28 15:13:39

在执行简单的usort之前填入缺失的值

代码语言:javascript
复制
$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']; });

稍显幻想的:

代码语言:javascript
复制
// 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']; });
票数 1
EN

Stack Overflow用户

发布于 2020-02-28 15:02:45

试着:

代码语言:javascript
复制
$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);

而不是

代码语言:javascript
复制
$sort = [];

foreach ($data as $key => $value)
    $sort[$key] = $value['position'];

array_multisort($sort, SORT_ASC, $data);
票数 1
EN

Stack Overflow用户

发布于 2020-02-28 15:05:50

解决了问题。

不确定这是否是最好的方法,但输出是所需的。

代码语言:javascript
复制
// 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
        )

)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60454029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档