natsort

(PHP 4, PHP 5, PHP 7, PHP 8)

natsort使用“自然顺序”算法对数组进行排序

描述

natsort(array &$array): true

此函数实现了一种排序算法,该算法以人类理解的方式对字母数字字符串进行排序,同时保持键值关联。这被称为“自然排序”。此算法与常规计算机字符串排序算法(在 sort() 中使用)之间的区别,可以在下面的示例中看到。

注意:

如果两个成员比较相等,它们将保留其原始顺序。在 PHP 8.0.0 之前,它们在排序数组中的相对顺序是未定义的。

注意:

将数组的内部指针重置为第一个元素。

参数

array

输入数组。

返回值

始终返回 true

变更日志

版本 描述
8.2.0 返回值类型现在为 true;之前是 bool.

示例

示例 #1 natsort() 示例演示基本用法

<?php
$array1
= $array2 = array("img12.png", "img10.png", "img2.png", "img1.png");

asort($array1);
echo
"标准排序\n";
print_r($array1);

natsort($array2);
echo
"\n自然顺序排序\n";
print_r($array2);
?>

以上示例将输出

Standard sorting
Array
(
    [3] => img1.png
    [1] => img10.png
    [0] => img12.png
    [2] => img2.png
)

Natural order sorting
Array
(
    [3] => img1.png
    [2] => img2.png
    [1] => img10.png
    [0] => img12.png
)

有关更多信息,请参见:Martin Pool 的 » 自然顺序字符串比较 页面。

示例 #2 natsort() 示例演示潜在的陷阱

<?php
echo "负数\n";
$negative = array('-5','3','-2','0','-1000','9','1');
print_r($negative);
natsort($negative);
print_r($negative);

echo
"零填充\n";
$zeros = array('09', '8', '10', '009', '011', '0');
print_r($zeros);
natsort($zeros);
print_r($zeros);
?>

以上示例将输出

Negative numbers
Array
(
    [0] => -5
    [1] => 3
    [2] => -2
    [3] => 0
    [4] => -1000
    [5] => 9
    [6] => 1
)
Array
(
    [2] => -2
    [0] => -5
    [4] => -1000
    [3] => 0
    [6] => 1
    [1] => 3
    [5] => 9
)

Zero padding
Array
(
    [0] => 09
    [1] => 8
    [2] => 10
    [3] => 009
    [4] => 011
    [5] => 0
)
Array
(
    [5] => 0
    [1] => 8
    [3] => 009
    [0] => 09
    [2] => 10
    [4] => 011
)

参见

添加说明

用户贡献说明 19 条说明

38
wyvern at greywyvern dot com
15 年前
无需包含您自己的 API 代码来对关联数组按键进行 natsort 排序。PHP 的内置函数(natsort 除外)可以完成这项工作。

<?php
uksort
($myArray, "strnatcmp");
?>
10
flash at minet dot net
21 年前
关于反向 natsort.. 可能更简单的方法是

function strrnatcmp ($a, $b) {
return strnatcmp ($b, $a);
}
13
Johan GENNESSON (php at genjo dot fr)
13 年前
注意 5.2.10 版本中的新行为。
请参见以下示例

<?php

$array
= array('1 bis', '10 ter', '0 PHP', '0', '01', '01 Ver', '0 ', '1 ', '1');

natsort($array);
echo
'<pre>';
print_r($array);
echo
'</pre>';
?>

5.2.6-1 将输出
数组
(
[3] => 0
[6] => 0
[2] => 0 OP
[4] => 01
[5] => 01 Ver
[8] => 1
[7] => 1
[0] => 1 bis
[1] => 10 ter
)

5.2.10 将输出
数组
(
[6] => 0
[3] => 0
[8] => 1
[4] => 01
[7] => 1
[5] => 01 Ver
[0] => 1 bis
[1] => 10 ter
[2] => 0 OP
)

问候
4
mbirth at webwriters dot de
20 年前
对于那些想要对二维数组的每个子数组的第一个元素进行 natsort 排序的人,以下几行代码应该可以完成这项工作。

<?php

function natsort2d(&$aryInput) {
$aryTemp = $aryOut = array();
foreach (
$aryInput as $key=>$value) {
reset($value);
$aryTemp[$key]=current($value);
}
natsort($aryTemp);
foreach (
$aryTemp as $key=>$value) {
$aryOut[] = $aryInput[$key];
}
$aryInput = $aryOut;
}

?>
4
anonymous at coward dot net
21 年前
反向 Natsort

function rnatsort($a, $b) {
return -1 * strnatcmp($a, $b);
}

usort($arr, "rnatsort");
8
xlab AT adaptiveNOSPAMarts DOT net
20 年前
在有限的测试下,natsort() 似乎对 IP 地址非常有效。对于我的需求,它比我之前使用的 ip2long()/long2ip() 转换代码少得多。
5
rasmus at flajm dot com
20 年前
要制作反向函数,您只需

function rnatsort(&$a){
natsort($a);
$a = array_reverse($a, true);
}
3
natcasesort.too
19 年前
我通过天真地使用此功能而被困住了 - 尝试对来自数码相机的图像文件名列表进行排序,其中文件名以零填充(例如 DSCF0120.jpg),将无法正确排序。
也许可以修改示例以展示这种行为
(例如,将数组设置为 -img0120.jpg','IMG0.png', 'img0012.png', 'img10.png', 'img2.png', 'img1.png', 'IMG3.png)
如果这个例子没有用图片的话,我一开始就能正确地写出代码了!
3
ale152
15 年前
注意: 负数。
<?php
$a
= array(-5,-2,3,9);
natsort($a);
print_r($a);
?>
将输出
Array ( [1] => -2 [0] => -5 [2] => 3 [3] => 9 )
1
bb7b5b9 at gmail dot com
8 年前
这让我浪费了许多宝贵的青春......natsort() 如果所有数字的小数位数不一致就会有bug。

(php 5.6.4-4ubuntu6.2)

<?php
$different_decimal_places_in_values
= array('D'=>'13.59', '14.6' => '14.6', 'C-' => '14.19');
natsort($a);
var_dump($a);

/*输出
array(3) {
'D' =>
string(5) "13.59"
'14.6' =>
string(4) "14.6" <----------- 排序错误
'C-' =>
string(5) "14.19"
}*/
?>

而这个

<?php
$same_num_decimal_places_in_values
= array('D'=>'13.59', '14.6' => '14.60', 'C-' => '14.19'); natsort($a); var_dump($a);

/*输出
array(3) {
'D' =>
string(5) "13.59"
'C-' =>
string(5) "14.19"
'14.6' =>
string(5) "14.60" <--------- 这是正确的顺序
}
*/

?>
1
lacent at gmail dot com
17 年前
页面下方还有一个 rnatsort 函数,但它在我需要的环境中不起作用。

这样做的原因
对数组的键进行自然排序,但需要反转顺序。

function rnatsort ( &$array = array() )
{
$keys = array_keys($array);
natsort($keys);
$total = count($keys) - 1;
$temp1 = array();
$temp2 = array();

// 将原始键分配给一个具有反向键集的数组,以便在 krsort() 中使用;
foreach ( $keys as $key )
{
$temp1[$total] = $key;
--$total;
}

ksort($temp1);

// 使用 krsort() 的顺序和原始数组的值设置新数组。
foreach ( $temp1 as $key )
{
$temp2[$key] = $array[$key];
}

$array = $temp2;
}
1
h3
18 年前
这个函数非常有用,但在某些情况下,例如,如果你想对 MySQL 查询结果进行排序,需要注意的是,MySQL 自带排序函数,这些函数比使用复杂的 php 算法对结果进行重新排序要快得多,尤其是在处理大型数组时。

例如; 'SELECT * FROM `table` ORDER BY columnName ASC, columnName2 DESC'
1
phpnet at moritz-abraham dot de
19 年前
除了 justin at redwiredesign dot com 发布的代码(我发现它非常有用)之外,这里还有一个函数可以对像这样的复杂数组进行排序
<?
$array['test0'] = array('main' => 'a', 'sub' => 'a');
$array['test2'] = array('main' => 'a', 'sub' => 'b');
$array['test3'] = array('main' => 'b', 'sub' => 'c');
$array['test1'] = array('main' => 'a', 'sub' => 'c');
$array['test4'] = array('main' => 'b', 'sub' => 'a');
$array['test5'] = array('main' => 'b', 'sub' => 'b');
?>

<?
$array[0] = array('main' => 1, 'sub' => 1);
$array[2] = array('main' => 1, 'sub' => 2);
$array[3] = array('main' => 2, 'sub' => 3);
$array[1] = array('main' => 1, 'sub' => 3);
$array[4] = array('main' => 2, 'sub' => 1);
$array[5] = array('main' => 2, 'sub' => 2);
?>
在一列或多列上。

代码
<? $array = array_natsort_list($array,'main','sub'); ?>
将使 $array 被排序如下
test0,test2,test1,test4,test5,test3

0,2,1,4,5,3.

你甚至可以向该函数提交更多值,因为它使用可变参数列表。该函数从最后一个参数开始排序,一直到第一个排序列。

对我来说,它对于排序具有子菜单甚至子子菜单的菜单非常有用。

我希望它也能帮到你。

以下是函数
<?
function array_natsort_list($array) {
// 对除了第一个参数以外的所有参数进行排序,从列表的末尾开始
for ($i=func_num_args();$i>1;$i--) {
// 获取要排序的列
$sort_by = func_get_arg($i-1);
// 清空数组
$new_array = array();
$temporary_array = array();
// 遍历原始数组
foreach($array as $original_key => $original_value) {
// 仅保存值
$temporary_array[] = $original_value[$sort_by];
}
// 对值进行排序
natsort($temporary_array);
// 删除重复的值
$temporary_array = array_unique($temporary_array);
// 遍历临时数组
foreach($temporary_array as $temporary_value) {
// 遍历原始数组
foreach($array as $original_key => $original_value) {
// 查找具有正确值的条目
if($temporary_value == $original_value[$sort_by]) {
// 保存到新数组中
$new_array[$original_key] = $original_value;
}
}
}
// 更新原始数组
$array = $new_array;
}
return $array;
}
?>
1
Malek Mohamed
6 年前
$array1 = $array2 = array('IMG0.png', 'img12.png', 'img10.png', 'img2.png', 'img1.png', 'IMG3.png');

natsort($array1);
echo "\n natsort(); \n";
print_r($array1);

sort($array2, SORT_NATURAL);
echo "\n sort() with SORT_NATURAL Option\n";
print_r($array2);

输出

natsort();
数组
(
[0] => IMG0.png
[5] => IMG3.png
[4] => img1.png
[3] => img2.png
[2] => img10.png
[1] => img12.png
)

sort() with SORT_NATURAL Option
数组
(
[0] => IMG0.png
[1] => IMG3.png
[2] => img1.png
[3] => img2.png
[4] => img10.png
[5] => img12.png
)

正如我们所看到的,它们的值相同,但键不同,对于 sort($array1, SORT_NATURAL | SORT_FLAG_CASE); 和 natcasesort($array2) 也是如此。
0
mvs dot php at gmail dot com
9 年前
要根据数组键进行自然排序,可以使用 uksort 函数。

<?php

echo "Sort by keys\n";
$smoothie = array('orange' => 1, 'apple' => 1, 'yogurt' => 4, 'banana' => 4);
print_r($smoothie);
uksort( $smoothie, 'strnatcmp');
print_r($smoothie)

?>

输出

Sort by keys
数组
(
[orange] => 1
[apple] => 1
[yogurt] => 4
[banana] => 4
)
数组
(
[apple] => 1
[banana] => 4
[orange] => 1
[yogurt] => 4
)

有关 uksort 的更多信息,请参见 https://php.net/manual/en/function.uksort.php,有关 strnatcmp 的用法,请参见 https://php.net/strnatcmp
0
@gmail bereikme
17 年前
以下是一个方便的函数,用于使用自然排序对一个或多个列的数组进行排序
<?php
// 例如: $records = columnSort($records, array('name', 'asc', 'addres', 'desc', 'city', 'asc'));

$globalMultisortVar = array();
function
columnSort($recs, $cols) {
global
$globalMultisortVar;
$globalMultisortVar = $cols;
usort($recs, 'multiStrnatcmp');
return(
$recs);
}

function
multiStrnatcmp($a, $b) {
global
$globalMultisortVar;
$cols = $globalMultisortVar;
$i = 0;
$result = 0;
while (
$result == 0 && $i < count($cols)) {
$result = ($cols[$i + 1] == 'desc' ? strnatcmp($b[$cols[$i]], $a[$cols[$i]]) : $result = strnatcmp($a[$cols[$i]], $b[$cols[$i]]));
$i+=2;
}
return
$result;
}

?>

您好,

- John
-2
AJenbo
15 年前
natsort 在使用零填充时可能不像你预期的那样,这是一个简单的示例。

<?php
$array
= array('09', '8', '10', '009', '011');
natsort($array);
?>
/*
数组
(
[3] => 009
[4] => 011
[0] => 09
[1] => 8
[2] => 10
)
*/
-1
lil at thedreamersmaze dot spam-me-not dot org
18 年前
mbirth at webwriters dot de 发布的这段有用的代码中缺少一个细节

<?php

function natsort2d(&$aryInput) {
$aryTemp = $aryOut = array();
foreach (
$aryInput as $key=>$value) {
reset($value);
$aryTemp[$key]=current($value);
}
natsort($aryTemp);
foreach (
$aryTemp as $key=>$value) {
$aryOut[$key] = $aryInput[$key];
// --------^^^^ add this if you want your keys preserved!
}
$aryInput = $aryOut;
}

?>
-2
dotancohen splat gmail spot com
7 年前
如其他注释中所述,natsort() 并不总是返回预期的排序顺序。在使用小数或 0 填充时,它似乎特别容易出错。我已经就此问题提交了以下错误报告
https://bugs.php.net/bug.php?id=74672
To Top