Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/239.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
php按自定义顺序对多维数组排序_Php_Arrays_Sorting_Multidimensional Array - Fatal编程技术网

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

php按自定义顺序对多维数组排序,php,arrays,sorting,multidimensional-array,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=>

按多维数组的一个键值(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\u order\u id数组中不可用,请将它们保留在最后(如上面的示例中,ID222和200不在$sort\u order\u id数组中,因此它根据它们以前的顺序排在最后)


我尝试了很多,但无法为它创建算法。。。我希望有人能帮我…

使用标准代码,按
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']];
});
您需要
usort()
,它允许您按定制需求进行排序。在本例中,您需要根据ID在
sort\u order\u 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);
});
试试这个

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);

@Jon的答案在使用spaceship操作符和空合并时可以更加简洁

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

代码:()

$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=数组翻转(['112','111','132','100']);
$idOutlier=计数($idPriorities);
乌斯波特(
$array,
函数($a,$b)使用($idPriorities,$idOutlier){
返回($idPriorities[$a['id']]??$idOutlier)($idPriorities[$b['id']]??$idOutlier);
}
);
var_导出($数组);
或使用PHP7.4+()

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

在排序之前翻转排序顺序数组将允许您使用
O(1)
数组查找替换
O(n)
array\u搜索
,可能使排序速度更快。您尝试过我的答案吗?为什么投反对票?请解释一下。。。这个问题以前在任何社区都没有被问过,请看@SatishSharma,上面的问题略有不同,因为如果子密钥id不在sortorder中,它就不会处理。正确阅读我的问题。这将尽可能慢。你实际上是在用一个不必要的高常数系数做一个计算。答案被接受,因为它比其他的更快。非常感谢。将行if(!isset($weights[$x['id']],$weights[$y['id']]){替换为if(!isset($weights[$x['id']])和&!isset($weights[$y['id']])){
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
        )

)
$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);
usort(
    $array,
    fn($a, $b) => ($idPriorities[$a['id']] ?? $idOutlier) <=> ($idPriorities[$b['id']] ?? $idOutlier)
);