php按自定义顺序排序多维数组

时间:2014-02-28 11:59:05

标签: php arrays sorting multidimensional-array

要求多维数组按其键值(asc或desc)排序太多次。 但我没有找到任何解决我的问题的方法,你必须通过预定义的自定义顺序中的一个键值对多维数组进行排序。

以数组为例

$array[0] = array('id'=> '111', value=>'abc');
$array[1] = array('id'=> '100', value=>'abc');
$array[2] = array('id'=> '132', value=>'abc');
$array[3] = array('id'=> '222', value=>'abc');
$array[4] = array('id'=> '112', value=>'abc');
$array[5] = array('id'=> '200', value=>'abc');

并按照以下数组中定义的顺序按子键“id”对此数组进行排序:

$sort_order_id = array('112','111','132','100');

所以结果将是

$array[0] = array('id'=> '112', value=>'abc');
$array[1] = array('id'=> '111', value=>'abc');
$array[2] = array('id'=> '132', value=>'abc');
$array[3] = array('id'=> '100', value=>'abc');
$array[4] = array('id'=> '222', value=>'abc');
$array[5] = array('id'=> '200', value=>'abc');

注意:如果某些id在$ sort_order_id数组中不可用,请将它们保留在最后(如上例所示,id 222和200不在$ sort_order_id数组中,因此它按照之前的顺序排在最后顺序)

我尝试了很多,但无法为此创建算法...我希望有人会帮助我......

4 个答案:

答案 0 :(得分:5)

采用标准代码按id排序数组:

usort($data, function($x, $y) { return $x['id'] - $y['id']; });

你想要做的不是通过id本身,而是通过每个id的“权重”(它代表你想要放入id的任意顺序)来排序。因此,创建一个数组,其中键是id,值是权重,并使用它将id转换为权重:

// array_flip turns 0 => 112, 1 => 111, ... into 122 => 0, 111 => 1, ...
$weights = array_flip(array('112','111','132','100'));

usort($data, function($x, $y) use($weights) {
    return $weights[$x['id']] - $weights[$y['id']];
});

更新:由于您还想处理没有指定权重的ID,因此您需要进一步扩展上述内容:

usort($data, function($x, $y) use($weights) {
    if (!isset($weights[$x['id']], $weights[$y['id']])) {
        // none of the ids have weight, so sort by bare id
        return $x['id'] - $y['id'];
    }
    else if (!isset($weights[$x['id']])) { 
        // x does not have weight, put it last
        return 1;
    }
    else if (!isset($weights[$y['id']])) {
        // y does not have weight, put it last
        return -1;
    }

    // both have weights, use them
    return $weights[$x['id']] - $weights[$y['id']];
});

答案 1 :(得分:1)

@Jon的答案对于宇宙飞船的操作者和null合并更为简洁。

一旦将id排序数组翻转,它便成为便利查找。 如果在排序数组中找不到给定行的id值,则将其“稍后”推送到输出数组中。

代码:(Demo

$array = [
    ['id' => '111', 'value' => 'abc'],
    ['id' => '100', 'value' => 'abc'],
    ['id' => '132', 'value' => 'abc'],
    ['id' => '222', 'value' => 'abc'],
    ['id' => '112', 'value' => 'abc'],
    ['id' => '200', 'value' => 'abc']
];

$idPriorities = array_flip(['112', '111', '132', '100']);
$idOutlier = count($idPriorities);

usort(
    $array,
    function($a, $b) use ($idPriorities, $idOutlier) {
        return ($idPriorities[$a['id']] ?? $idOutlier) <=> ($idPriorities[$b['id']] ?? $idOutlier);
    }
);

var_export($array);

或PHP7.4 +(Demo

usort(
    $array,
    fn($a, $b) => ($idPriorities[$a['id']] ?? $idOutlier) <=> ($idPriorities[$b['id']] ?? $idOutlier)
);

答案 2 :(得分:0)

您需要usort(),这样您就可以按照定制的要求进行排序。在您的情况下,您需要按照sort_order_id数组中ID的位置进行排序。

$array = array(
    array('id'=> '111', value=>'abc'),
    array('id'=> '100', value=>'abc'),
    array('id'=> '132', value=>'abc'),
    array('id'=> '112', value=>'abc')
);
$sort_order_id = array('112','111','132','100');
usort($array, function($a, $b) {
    global $sort_order_id;
    return array_search($a['id'], $sort_order_id) - array_search($b['id'], $sort_order_id);
});

答案 3 :(得分:0)

尝试这个

echo "<pre>";

$array[0] = array('id'=> '111', 'value'=>'abc');
$array[1] = array('id'=> '100', 'value'=>'abc');
$array[2] = array('id'=> '132', 'value'=>'abc');
$array[3] = array('id'=> '222', 'value'=>'abc');
$array[4] = array('id'=> '112', 'value'=>'abc');
$array[5] = array('id'=> '200', 'value'=>'abc');

$arr_temp = $array;
$array = array();
$sort_order_id = array('112','111','132','100');
foreach($sort_order_id as $order_id)
{
    foreach($arr_temp as $key=>$arr)
    {
        if($arr['id'] == $order_id)
        {
            $array[] = $arr;
            unset($arr_temp[$key]);
        }
    }
}

foreach($arr_temp as $key=>$arr)
{
        $array[] = $arr;
        unset($arr_temp[$key]);
}

print_r($array);

输出:

Array
(
    [0] => Array
        (
            [id] => 112
            [value] => abc
        )

    [1] => Array
        (
            [id] => 111
            [value] => abc
        )

    [2] => Array
        (
            [id] => 132
            [value] => abc
        )

    [3] => Array
        (
            [id] => 100
            [value] => abc
        )

    [4] => Array
        (
            [id] => 222
            [value] => abc
        )

    [5] => Array
        (
            [id] => 200
            [value] => abc
        )

)