对平面数组进行排序,以便多个指定值出现在未提及的值之前

问题描述 投票:0回答:5

我想对一维数组进行排序,以便其中两个值位于第一个和第二个位置。

$array = ["Apple", "Orange", "Banana", "Melon"];

我想对数组进行排序,首先是“Orange”,然后是“Melon”。

想要的结果:

["Orange", "Melon", "Apple", "Banana"];

我查看了 PHP 的排序函数,但没有找到排序函数来做到这一点。

php arrays sorting
5个回答
6
投票

您要找的是usort,您可以指定自定义函数对数组进行排序

示例:

function cmp($a, $b)
{
    if ($a == "Orange") {
        return 1;
    }
    if ($b == "Orange") {
        return -1;
    }

    return strcmp($a, $b);// or any other sort you want
}

$arr = array("Apple", "Orange", "Banana", "Melon");

usort($arr, "cmp");

4
投票

另一种解决方案;使用自定义函数将元素移动到数组的开头

function __unshift(&$array, $value){
    $key = array_search($value, $array);
    if($key) unset($array[$key]);
    array_unshift($array, $value);  
    return $array;
}

$a = array("Apple", "Orange", "Banana", "Melon");
__unshift($a, "Melon");
__unshift($a, "Orange");
print_r($a);

输出:

Array
(
    [0] => Orange
    [1] => Melon
    [2] => Apple
    [3] => Banana
)

演示

或者您可以使用以下命令使用另一个具有重新排序索引的数组来重新排序数组

function __reorder(&$a, &$b){
    $c = array();
    foreach($b as $index){
        array_push($c, $a[$index]);
    }
    return $c;
}

// the original array
$a = array("Apple", "Orange", "Banana", "Melon");
// an array with reordered index 
$b = array(1, 3, 0, 2);
$c = __reorder($a, $b);
print_r($c);

演示


1
投票

这里的解决方案比其他提供的解决方案更长,但更灵活。您可以轻松扩展或更改要首先排序的项目数组。

$array = array("Apple", "Orange", "Banana", "Melon");
$sort_first = array("Orange", "Melon");

usort($array, function ($a, $b) use ($sort_first) {
    $order_a = array_search( $a, $sort_first );
    $order_b = array_search( $b, $sort_first );

    if ($order_a === false && $order_b !== false) {
        return 1;
    } elseif ($order_b === false && $order_a !== false) {
        return -1;
    } elseif ($order_a === $order_b) {
        return $a <=> $b;
    } else {
        return $order_a <=> $order_b;
    }
});

// Result: $array = array("Orange", "Melon", "Apple", "Banana");

如果您要排序的项目不是字符串(例如数组或对象),也可以轻松更改该函数。这是一个对对象数组进行排序的示例:

// Assuming $array is an array of users with a getName method
$sort_first = array("Sam", "Chris");

usort($array, function ($a, $b) use ($sort_first) {
    $order_a = array_search( $a->getName(), $sort_first );
    $order_b = array_search( $b->getName(), $sort_first );

    if ($order_a === false && $order_b !== false) {
        return 1;
    } elseif ($order_b === false && $order_a !== false) {
        return -1;
    } elseif ($order_a === $order_b) {
        return $a->getName() <=> $b->getName();
    } else {
        return $order_a <=> $order_b;
    }
});

// $array will now have users Sam and Chris sorted first,
// and the rest in alphabetical order by name

0
投票
$paths = array_merge(
    array_intersect(["Orange", "Melon"], ["Apple", "Orange", "Banana", "Melon"]),
    array_diff(["Apple", "Orange", "Banana", "Melon"], ["Orange", "Melon"])
);

0
投票

声明一个查找数组,其中“Orange”的值为

0
,“Melon”的值为
1
。当遇到未提及的值时,为其指定一个比所有列出的值更高的数值。对这些整数进行排序将使任务变得简单。 (演示)

$array = ["Apple", "Orange", "Banana", "Melon"];
$priority = array_flip(["Orange", "Melon"]);

usort(
    $array,
    fn($a, $b) => ($priority[$a] ?? PHP_INT_MAX) <=> ($priority[$b] ?? PHP_INT_MAX)
);

var_export($array);

或者,因为您的输入数组的值都是唯一的,您只需将未提及的值附加到指定订单数组的末尾。 (演示)

$array = ["Apple", "Orange", "Banana", "Melon"];
$priority = ["Orange", "Melon"];
var_export(
    array_merge($priority, array_diff($array, $priority))
);
© www.soinside.com 2019 - 2024. All rights reserved.