我正在尝试根据key=>value
对数组进行排序,但我无法完成此操作。这是我正在编写的代码:
$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
);
其中value定义项目应移动的位置。换句话说,让我们举一个例子:'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' => []
];
几乎相同,但这就是数组应该看起来的样子(只是一个例子)和[]
的数组应该有其他键我只是不在这里写,因为相关的是{{1 }}
答案 0 :(得分:1)
$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);
编辑刚刚意识到我错过了数组键的重要性。也许你根本不需要密钥,但为了完整性,这里有一个修改过的解决方案,它也保留了密钥:
$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);
答案 1 :(得分:1)
Imho这不是一个排序问题,因为你有多个元素不可能排序(空值应该保持在同一个地方,在数组的开头或结尾)。
您的问题与某些元素在正确位置的定位有关。 我认为你应该在迭代数组时解决它。
答案 2 :(得分:1)
让我们试试这个
http://sandbox.onlinephpfunctions.com/code/f72cc2ef661f805a9f5a8a491c2cf5455ed31c60
$arr = array(
'183034' => 9,
'183033' => 6,
'183032' => 3,
'183002' => null,
'182973' => null,
'182971' => null,
'182969' => null,
'182999' => null,
'182997' => 10,
'182995' => null,
'182962' => null,
'182948' => null
);
// sort by value and maintaiming key value association
// separate null values from numeric values
// null values a start of array
// numeric values at end of array
asort($arr, SORT_NATURAL);
// this is a temporary array used to store every single row from $arr
// as a array value
// the keys of this array start with 0 and are positional
$arrTemp = [];
foreach ( $arr as $key => $value ) {
if ( is_numeric($value) ) {
// insert into $arrTemp the numeric value at the correct position
// because we arsorted $arr before, the splice does not push
// numeric values behind
array_splice($arrTemp, $value, 0, array(array($key => $value)));
} else {
// these are the null values, they fill up the start of $arrTemp
$arrTemp[] = array($key => $value);
}
}
$arrOut = array();
// get the array of arrays back into a hash array
foreach ( $arrTemp as $value ) {
list($key, $val) = each($value);
$arrOut[$key] = $val;
}
print_r($arrOut);
来自OP的规格改变之后就是这个解决方案
http://sandbox.onlinephpfunctions.com/code/f72cc2ef661f805a9f5a8a491c2cf5455ed31c60
$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;
}
}