Php 基于键对数组排序=>;值对

Php 基于键对数组排序=>;值对,php,arrays,algorithm,sorting,Php,Arrays,Algorithm,Sorting,我试图根据键=>值对数组进行排序,但无法完成此操作。以下是我正在制定的代码: $arr = [ '183034' => 9, '183033' => 6, '183032' => 3, '183002' => null, '182973' => null, '182971' => null, '182969' => null, '182999' => null, '182997

我试图根据
键=>值对数组进行排序,但无法完成此操作。以下是我正在制定的代码:

$arr = [
    '183034' => 9,
    '183033' => 6,
    '183032' => 3,
    '183002' => null,
    '182973' => null,
    '182971' => null,
    '182969' => null,
    '182999' => null,
    '182997' => null,
    '182995' => null,
    '182962' => null,
    '182948' => null
];

$arrTemp = [];

foreach($arr as $key => $value) {
    $arrTemp[$key] = $value;
}

array_multisort($arrTemp, SORT_NUMERIC, $arr);

var_export($arrTemp);
输出为:

#php test.php
array (
  0 => NULL,
  1 => NULL,
  2 => NULL,
  3 => NULL,
  4 => NULL,
  5 => NULL,
  6 => NULL,
  7 => NULL,
  8 => NULL,
  9 => 3,
  10 => 6,
  11 => 9,
)
但我期望的是:

array (
    '183002' => null,
    '182973' => null,
    '182971' => null,
    '183032' => 3,
    '182969' => null,
    '182999' => null,
    '183033' => 6,
    '182997' => null,
    '182995' => null,
    '183034' => 9,
    '182962' => null,
    '182948' => null    
);
其中值定义项目应移动到的位置。换言之,让我们以文字为例:
'183032'=>3
此项在结果数组中保持位置3,因此我应该做的是保持相同的数组顺序,但将该项移动到位置3,正如您在输出数组中可能注意到的那样。同样对于
'183033'=>6
,其中这个保持位置6,所以我对整个数组重新排序,将其移动到位置6,依此类推。有人能给我一些帮助吗

更新

如果我将原来的
$arr
更改为:

$arr = [
    '183034' => ['sort_position' => 9],
    '183033' => ['sort_position' => 5],
    '183032' => ['sort_position' => 3],
    '183002' => [],
    '182973' => [],
    '182971' => [],
    '182969' => [],
    '182999' => [],
    '182997' => [],
    '182995' => [],
    '182962' => [],
    '182948' => []
];
几乎相同,但这就是数组的外观(只是一个示例),带有
[]
的数组应该有其他键,我只是不在这里写它们,因为相关的是
排序位置

$arr=[
$arr = [
    '183034' => ['sort_position' => 9],
    '183033' => ['sort_position' => 5],
    '183032' => ['sort_position' => 3],
    '183002' => [],
    '182973' => [],
    '182971' => [],
    '182969' => [],
    '182999' => [],
    '182997' => [],
    '182995' => [],
    '182962' => [],
    '182948' => []
];
$count = count($arr);
$tmp=[];
//sort by key descending
krsort($arr);
foreach($arr as $key=>$val){
    //if element has a sort position
    if(isset($val['sort_position'])){
        //save it in tmp, indexed by sort position
        $tmp[$val['sort_position']]=$val;
        //and remove it from original array
        unset($arr[$key]);
    }
}
//Note $arr now only contains elements without sort position

$out=[];
//build new array of same length as original
for($i=0; $i < $count; $i++){
    //if there is an element in temp with this sort position, use it
    //else grab the next one from the non sort position elements
    $out[] = isset($tmp[$i])? $tmp[$i] : array_shift($arr);
}

var_dump($out);
'183034'=>[sort_position'=>9], “183033”=>5], '183032'=>, '183002' => [], '182973' => [], '182971' => [], '182969' => [], '182999' => [], '182997' => [], '182995' => [], '182962' => [], '182948' => [] ]; $count=计数($arr); $tmp=[]; //按键降序排序 krsort($arr); foreach($arr作为$key=>$val){ //if元素具有排序位置 如果(isset($val['sort_position'])){ //将其保存在tmp中,按排序位置索引 $tmp[$val['sort_position']]=$val; //并将其从原始阵列中移除 未设置($arr[$key]); } } //注意$arr现在只包含没有排序位置的元素 $out=[]; //构建与原始阵列长度相同的新阵列 对于($i=0;$i<$count;$i++){ //如果temp中有一个元素具有此排序位置,请使用它 //否则,从非排序位置元素中获取下一个 $out[]=isset($tmp[$i])?$tmp[$i]:数组移位($arr); } var_dump($out);
EDIT刚刚意识到我忽略了数组键的重要性。也许你根本不需要钥匙,但为了完整起见,这里有一个修改过的解决方案,它也保留了钥匙:

$count = count($arr);
$has_sortorder=[];
$no_sortorder=[];
krsort($arr);
foreach($arr as $key=>$val){
    if(isset($val['sort_position'])){
        $has_sortorder[$val['sort_position']]=[$key, $val];
    }else{
        $no_sortorder[]=[$key, $val];
    }
}


$out=[];
for($i=0; $i < $count; $i++){
    if(isset($has_sortorder[$i])){
        $out[$has_sortorder[$i][0]] = $has_sortorder[$i][1];
    }else{
        $element = array_shift($no_sortorder);
        $out[$element[0]] = $element[1];
    }
}

var_dump($out);
$count=count($arr);
$has_sortorder=[];
$no_sortorder=[];
krsort($arr);
foreach($arr作为$key=>$val){
如果(isset($val['sort_position'])){
$has_sortorder[$val['sort_position']]=[$key,$val];
}否则{
$no_sortorder[]=[$key,$val];
}
}
$out=[];
对于($i=0;$i<$count;$i++){
if(isset($has_sortorder[$i])){
$out[$has_sortorder[$i][0]=$has_sortorder[$i][1];
}否则{
$element=array\u shift($no\u sortorder);
$out[$element[0]]=$element[1];
}
}
var_dump($out);
$arr=[
'183034'=>[sort_position'=>9],
“183033”=>5],
'183032'=>,
'183002' => [],
'182973' => [],
'182971' => [],
'182969' => [],
'182999' => [],
'182997' => [],
'182995' => [],
'182962' => [],
'182948' => []
];
$count=计数($arr);
$tmp=[];
//按键降序排序
krsort($arr);
foreach($arr作为$key=>$val){
//if元素具有排序位置
如果(isset($val['sort_position'])){
//将其保存在tmp中,按排序位置索引
$tmp[$val['sort_position']]=$val;
//并将其从原始阵列中移除
未设置($arr[$key]);
}
}
//注意$arr现在只包含没有排序位置的元素
$out=[];
//构建与原始阵列长度相同的新阵列
对于($i=0;$i<$count;$i++){
//如果temp中有一个元素具有此排序位置,请使用它
//否则,从非排序位置元素中获取下一个
$out[]=isset($tmp[$i])?$tmp[$i]:数组移位($arr);
}
var_dump($out);
EDIT刚刚意识到我忽略了数组键的重要性。也许你根本不需要钥匙,但为了完整起见,这里有一个修改过的解决方案,它也保留了钥匙:

$count = count($arr);
$has_sortorder=[];
$no_sortorder=[];
krsort($arr);
foreach($arr as $key=>$val){
    if(isset($val['sort_position'])){
        $has_sortorder[$val['sort_position']]=[$key, $val];
    }else{
        $no_sortorder[]=[$key, $val];
    }
}


$out=[];
for($i=0; $i < $count; $i++){
    if(isset($has_sortorder[$i])){
        $out[$has_sortorder[$i][0]] = $has_sortorder[$i][1];
    }else{
        $element = array_shift($no_sortorder);
        $out[$element[0]] = $element[1];
    }
}

var_dump($out);
$count=count($arr);
$has_sortorder=[];
$no_sortorder=[];
krsort($arr);
foreach($arr作为$key=>$val){
如果(isset($val['sort_position'])){
$has_sortorder[$val['sort_position']]=[$key,$val];
}否则{
$no_sortorder[]=[$key,$val];
}
}
$out=[];
对于($i=0;$i<$count;$i++){
if(isset($has_sortorder[$i])){
$out[$has_sortorder[$i][0]=$has_sortorder[$i][1];
}否则{
$element=array\u shift($no\u sortorder);
$out[$element[0]]=$element[1];
}
}
var_dump($out);

Imho这不是排序问题,因为有多个元素无法排序(空值应全部保留在同一位置,在数组的开头或结尾)

您的问题与某些元素在正确位置的定位有关。
我认为应该迭代数组来解决这个问题。

这不是排序问题,因为有多个元素无法排序(空值应该保持在相同的位置,在数组的开头或结尾)

您的问题与某些元素在正确位置的定位有关。 我想你应该迭代数组来解决它。

让我们试试这个


编辑 在OP的规格更改之后,它将成为此解决方案

$arr=array(
'183034'=>数组('sort_position'=>9),
'183033'=>数组('sort_position'=>5),
'183032'=>数组('sort_position'=>3),
“183002”=>array(),
“182973”=>array(),
“182971”=>array(),
“182969”=>array(),
“182999”=>array(),
“182997”=>array(),
“182995”=>array(),
“182962”=>array(),
“182948”=>array(),
);
$arrTemp=[];
uasort($arr,'compare_function');
foreach($arr作为$key=>$value){
如果(!empty($value)&&is_numeric($value['sort_position'])){
数组拼接($arrTemp,$value['sort_position'],0,数组(数组($key=>$value));
}否则{
$arrTemp[]=array($key=>$value);
}
}
$arr = array(
    '183034' => array('sort_position' => 9),
    '183033' => array('sort_position' => 5),
    '183032' => array('sort_position' => 3),
    '183002' => array(),
    '182973' => array(),
    '182971' => array(),
    '182969' => array(),
    '182999' => array(),
    '182997' => array(),
    '182995' => array(),
    '182962' => array(),
    '182948' => array(),
);

$arrTemp = [];

uasort($arr, 'compare_function');


foreach ( $arr as $key => $value ) {
  if ( !empty($value) && is_numeric($value['sort_position']) ) {
    array_splice($arrTemp, $value['sort_position'], 0, array(array($key => $value)));
  } else {
    $arrTemp[] = array($key => $value);
  }
}

$arrOut = array();

foreach ( $arrTemp as $value ) {
  list($key, $val) = each($value);
  $arrOut[$key] = $val;
}

print_r($arrOut);


function compare_function($a, $b) {
    if ( isset($a['sort_position']) && !isset($b['sort_position']) ) {
        return 1;
    }
    if ( isset($b['sort_position']) && !isset($a['sort_position']) ) {
        return -1;
    }
    if ( isset($a['sort_position']) && isset($b['sort_position']) ) {
        if ( (int) $a['sort_position'] == (int) $b['sort_position']  ) {
            return 0;
        }
        return (int) $a['sort_position'] < (int) $b['sort_position'] ? -1 : 1;
    }

}