【问题标题】:PHP array_multisort not sorting my multidimensional array as expectedPHP array_multisort 没有按预期对我的多维数组进行排序
【发布时间】:2013-06-26 15:47:29
【问题描述】:

我正在尝试使用 array_multisort 函数对多维数组进行排序

我期待多维数组使用 $sort 中的值对自身进行排序。 $sort 与我的多维数组的体积元素有关。

我希望名称元素按以下顺序排列:

'name' => 8, 'name' => 6, 'name' => 7, 'name' => 9', 'name' => 10, 'name' => 10,

退回的订单与预期不符。也许我误解了 array_multisort 的工作原理?

Array
(
[test1] => Array
    (
        [volume] => 67
        [edition] => 2
        [name] => 6
        [num] => 2
    )

[test2] => Array
    (
        [volume] => 86
        [edition] => 1
        [name] => 7
        [type] => 2
    )

[test3] => Array
    (
        [volume] => 85
        [edition] => 6
        [name] => 8
        [type] => 2
    )

[test4] => Array
    (
        [volume] => 98
        [edition] => 2
        [name] => 9
        [type] => 2
    )

[test5] => Array
    (
        [volume] => 86
        [edition] => 6
        [name] => 10
        [type] => 2
    )

[test6] => Array
    (
        [volume] => 67
        [edition] => 7
        [name] => 11
        [type] => 2
    )

)

$sort = array(85, 67, 86, 98, 86, 67);
array_multisort($sort, $data);

这是原始数组:

$data['test1'] = array('volume' => 67, 'edition' => 2, 'name' => 6, 'num' => 2,);
$data['test2'] = array('volume' => 86, 'edition' => 1, 'name' => 7, 'type' => 2,);
$data['test3'] = array('volume' => 85, 'edition' => 6, 'name' => 8, 'type' => 2,);
$data['test4'] = array('volume' => 98, 'edition' => 2, 'name' => 9, 'type' => 2,);
$data['test5'] = array('volume' => 86, 'edition' => 6, 'name' => 10, 'type' => 2,);
$data['test6'] = array('volume' => 67, 'edition' => 7, 'name' => 11, 'type' => 2,);

【问题讨论】:

  • 能否贴出原始数组,以及如何调用排序函数?
  • 就像@dognose 说的那样,如果我们不知道数组的原始顺序,就很难说什么——但它似乎按预期工作。但是,如果您只想按 name 属性进行排序,也许您应该改用 uasort
  • @dognose - 他确实这么说:我期待多维数组使用 $sort 中的值对自身进行排序,因此名称元素将按此顺序排列
  • $sort 是一个包含卷元素值的数组。不要以为我在帖子中说的很清楚。
  • 看我的回答。如果$sort 包含卷元素,您的调用将类似于array_multisort($sort, SORT_ASC, $data)

标签: php arrays multidimensional-array


【解决方案1】:

使用数组Multisort,您可以根据列进行排序。这是一个示例,您可以轻松地按“所有”可用列进行排序:

<?
$data['test1'] = array('volume' => 67, 'edition' => 2, 'name' => 6, 'type' => 2);
$data['test2'] = array('volume' => 86, 'edition' => 1, 'name' => 7, 'type' => 2);
$data['test3'] = array('volume' => 85, 'edition' => 6, 'name' => 8, 'type' => 2);
$data['test4'] = array('volume' => 98, 'edition' => 2, 'name' => 9, 'type' => 2);
$data['test5'] = array('volume' => 86, 'edition' => 6, 'name' => 10, 'type' => 2);
$data['test6'] = array('volume' => 67, 'edition' => 7, 'name' => 11, 'type' => 2);

//Create index rows
foreach ($data as $row) {
  foreach ($row as $key => $value){
    ${$key}[]  = $value; //Creates $volume, $edition, $name and $type arrays.
  }  
}

//ex: sort by edition asc, then by name DESC:

array_multisort($edition, SORT_ASC, $name, SORT_DESC, $data);

echo "<pre>";
print_r($data);
echo "</pre>";
?>

将导致(首先按版本 ASC,然后按名称 DESC): (按名称 ASC 排序,将交换 test4 和 test1 ofc。)

Array
(
    [test2] => Array
        (
            [volume] => 86
            [edition] => 1
            [name] => 7
            [type] => 2
        )

    [test4] => Array
        (
            [volume] => 98
            [edition] => 2
            [name] => 9
            [type] => 2
        )

    [test1] => Array
        (
            [volume] => 67
            [edition] => 2
            [name] => 6
            [type] => 2
        )

    [test5] => Array
        (
            [volume] => 86
            [edition] => 6
            [name] => 10
            [type] => 2
        )

    [test3] => Array
        (
            [volume] => 85
            [edition] => 6
            [name] => 8
            [type] => 2
        )

    [test6] => Array
        (
            [volume] => 67
            [edition] => 7
            [name] => 11
            [type] => 2
        )

)

您可以根据需要添加任意数量的列。我希望这会有所帮助。

编辑:至于你的问题: 不,Array MultiSort 不适用于根据预定义的顺序对数组进行排序。 array_multisort 所做的是: 它根据给定的条件(asc 或 desc)对数组进行排序,并将其他数组中的条目相对向上或向下移动,不会违反任何其他数组的排序

基本示例:

$letters = array("b","a","c");
$numbers = array(5,4,2);

调用array_multisort($letters,$numbers) 将导致a,b,c 和(a 向上移动,b 向下)4,5,2

如果示例是:

$letters = array("b","a","a");
$numbers = array(5,4,2);

首先将应用相同的排序:(a,a,b -> 4,2,5),但随后 array_multisort 注意到,它可以将 as 交换为排序 2 和 4。最终结果:a,a,b -> 2,4,5

回到你的问题:

要按预定义的顺序排序,您可以执行以下操作:

1.) 定义您的订单,即$order = array("a","z","b");

2.) 使用用户函数调用 uasort

3.) 在该排序函数中,使用数组翻转和关联访问来获取实际位置:

$items = array("a","b","z","a","z","z");

uasort($items, "sortByPredefinedOrder");

function sortByPredefinedOrder($leftItem, $rightItem){
  $order = array("a","z","b","x"); //defined somewhere

  $flipped = array_flip($order); //so we can access "position by value"

  $leftPos = $flipped[$leftItem];
  $rightPos = $flipped[$rightItem];
  return $leftPos >= $rightPos;   
}

print_r($items); //Array ( [0] => a [3] => a [2] => z [4] => z [5] => z [1] => b )

对于您的多维输入,您可以使用

  $leftPos = $flipped[$leftItem["volume"]];
  $rightPos = $flipped[$rightItem["volume"]];

但是ofc。这将要求您预测预定义顺序数组中的所有值,并使用适当的返回值处理 IndexOutOfBoundExceptions。

【讨论】:

  • 这是一个非常有用的例子,我已经收藏了一个,但这并不是我想要的。我需要根据我的 $sort 数组中的值执行自定义排序。我不一定能通过 ASC 或 DESC 订购。
  • 你可以用uasort做同样的事情,但不必构建所有额外的数组。
  • @monkey64 添加了使用预定义顺序进行排序的示例......嗯......在我的答案底部:D
  • 您的示例非常出色且易于理解。感谢您为此花费的时间,并希望它对未来的访问者有所帮助。
猜你喜欢
  • 2020-10-25
  • 1970-01-01
  • 2019-10-05
  • 2013-11-30
  • 1970-01-01
  • 2016-10-31
  • 2012-06-15
相关资源
最近更新 更多