如何在数组上执行自定义排序并保留键值

3

我目前有这个代码:

array(0=>'foo', 1=>'bar', 3=>'baz', 4=>'boo', 5=>'wahoo');

What I want is this:

array(0=>'foo', 3=>'baz', 1=>'bar', 5=>'wahoo', 4=>'boo');

这是一个简化的例子,我的实际数组更大、更复杂,因此不能轻易地分成较小的部分并重新组合。

我一直在尝试使用uksort来解决这个问题,我认为这是前进的最佳方式,但似乎无法得到我想要的结果。

编辑:

我认为我的简化示例实际上混淆了问题。这是我的实际数组以及我想要最终达到的结果。

Array
(
    [1820] => Safety
    [1821] => Security
    [1822] => Digital Life
    [1893] => Privacy and Digital Footprints
    [1823] => Connected Culture
    [1824] => Respecting Creative Work
    [1825] => Searching
    [1826] => Research and Evaluation
    [1836] => Self-Expression and Identity
)

Array
(
    [1820] => Safety
    [1821] => Security
    [1822] => Digital Life
    [1893] => Privacy and Digital Footprints
    [1823] => Connected Culture
    [1836] => Self-Expression and Identity
    [1824] => Respecting Creative Work
    [1825] => Searching
    [1826] => Research and Evaluation
)

我几乎已经完成了一个数值排序,但有两个项目不在顺序中。


它是一个数字数组还是关联数组? - Jared Farrish
1
@Jared - 一旦键值对不按顺序排列,它就是关联数组(从技术上讲,当PHP看到数字时,它始终是关联数组,并进行一些特殊处理)。 - evan
1
排序标准是什么?例如,为什么baz要排在bar之前,但boo却排在wahoo之后? - hakre
1
在这种情况下,我强烈建议创建一个更好的问题,更准确地反映您想要做什么。以下是一些其他选项:首先,使用现有内容并使比较函数了解每个项目的优先级。其次,更改数据结构以包括优先级,并在比较函数中按它们进行排序。 - evan
所有的键都是提前“已知”的吗?你能在脚本中列出所有出现的键吗? - mickmackusa
显示剩余3条评论
3个回答

2

您实际上需要使用uasort函数。

它可以让您使用自己的排序函数并保留键。

uksort基于键进行排序,而不是值。

示例:
http://codepad.viper-7.com/E8oZ2g

function cmp($a, $b) {
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

// Array to be sorted
$array = array('a', 'b', 'c', 'b');

echo "<pre>";
print_r($array);
echo "</pre>";

// Sort and print the resulting array
uasort($array, 'cmp');
echo "<pre>";
print_r($array);
echo "</pre>";

输出:

Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => b
)

Array
(
    [0] => a
    [3] => b
    [1] => b
    [2] => c
)

1
在这个例子中,键和值一起移动。这就是uasort的作用,请参见添加的示例。 - evan
真的(就像你看到的那样,我一直在想)。唯一需要补充的是,需要使用foreach()循环来访问新数组的顺序:http://codepad.viper-7.com/kQuwis。(我更喜欢在答案中看到您的代码,而不仅仅是在codepad页面上,但无论如何都会给个赞。) - Jared Farrish
你不能“停止”排序。如果你有一些特殊的算法来进行排序,那么你需要将其作为比较函数。但是它必须在将每个值与其他每个值进行比较时都能正常工作。 - evan
@MarkFerree:要“停止”排序,您应该在问题中指定标准并说明您想要这样做,因为现在不清楚您是否要求它;) - hakre
已更新问题并附上了实际标准。 - Mark Ferree
显示剩余3条评论

1

根据讨论得出的新答案。

使用uksort()

在比较函数中进行匹配并更改它们。

以下是适用于您上面示例的示例。

function updateKey($key)
{
   switch($key)
   {
     case 1893:
       return 1822.5;

     case 1836:
       return 1823.5;

     default:
       return $key;
   }
}

function cmp($a, $b) 
{
    $a = updateKey($a);
    $b = updateKey($b);

    // you must do the compare this way for floats (instead of just subtracting) because php implemented the compare callback poorly
    if ($a == $b) 
    {
        return 0;
    }

    return ($a < $b) ? -1 : 1;
}

uksort($array, 'cmp');

0
//randomize array preserving keys
function shuffle_assoc( $array )
{
   $keys = array_keys( $array );
   shuffle( $keys );
   return array_merge( array_flip( $keys ) , $array );
}

源代码:http://www.php.net/manual/zh/function.shuffle.php

请注意,此函数返回一个新的数组,而不是修改原始数组。


抱歉,我认为标题中的“随机”一词让它变得混乱了,移动的物品很重要。我的意思是,结果的顺序没有任何可预测性。 - Mark Ferree
1
你想使用什么样的公式或函数从原始数组到结果数组?它们按特定顺序排序还是只是手动分配? - Brian Glaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接