文字

natcasesort

(PHP 4, PHP 5, PHP 7)

natcasesort 用“自然排序”算法对数组进行不区分大小写字母的排序

说明

bool natcasesort ( array &$array )

natcasesort() natsort() 函数的不区分大小写字母的版本。

本函数实现了一个和人们通常对字母数字字符串进行排序的方法一样的排序算法并保持原有键/值的关联,这被称为“自然排序”。

参数

array

输入的数组。

返回值

成功时返回 TRUE , 或者在失败时返回 FALSE

范例

Example #1 natcasesort() 例子

<?php
$array1 
$array2  = array( 'IMG0.png' 'img12.png' 'img10.png' 'img2.png' 'img1.png' 'IMG3.png' );

sort ( $array1 );
echo 
"Standard sorting\n" ;
print_r ( $array1 );

natcasesort ( $array2 );
echo 
"\nNatural order sorting (case-insensitive)\n" ;
print_r ( $array2 );
?>

以上例程会输出:

Standard sorting
Array
(
    [0] => IMG0.png
    [1] => IMG3.png
    [2] => img1.png
    [3] => img10.png
    [4] => img12.png
    [5] => img2.png
)Natural order sorting (case-insensitive)
Array
(
    [0] => IMG0.png
    [4] => img1.png
    [3] => img2.png
    [5] => IMG3.png
    [2] => img10.png
    [1] => img12.png
)

更多信息见 Martin Pool 的 » Natural Order String Comparison 页面。

参见

  • natsort() - 用“自然排序”算法对数组排序
  • 数组排序函数对比
  • strnatcmp() - 使用自然排序算法比较字符串
  • strnatcasecmp() - 使用“自然顺序”算法比较字符串(不区分大小写)

用户评论:

[#1] w-dot-rosenbach-at-netskill-de [2010-12-14 09:45:44]

Sorting UTF-8 by arbitrary order:

<?php
mb_internal_encoding
("UTF-8");

class 
utf_8_german
{
  
// everything else is sorted at the end
  
static $order '0123456789Aa??BbCcDdEeFfGgHhIiJjKkLlMm
NnOo??PpQqRrSs?TtUu???VvWwXxYyZz'
;
  static 
$char2order;
  
  static function 
cmp($a$b) {
    if (
$a == $b) {
        return 
0;
    }
    
    
// lazy init mapping
    
if (empty(self::$char2order))
    {
      
$order 1;
      
$len mb_strlen(self::$order);
      for (
$order=0$order<$len; ++$order)
      {
        
self::$char2order[mb_substr(self::$order$order1)] = $order;
      }
    }
    
    
$len_a mb_strlen($a);
    
$len_b mb_strlen($b);
    
$max=min($len_a$len_b);
    for(
$i=0$i<$max; ++$i)
    {
      
$char_amb_substr($a$i1);
      
$char_bmb_substr($b$i1);
      
      if (
$char_a == $char_b) continue;
      
$order_a = (isset(self::$char2order[$char_a])) ? self::$char2order[$char_a] : 9999;
      
$order_b = (isset(self::$char2order[$char_b])) ? self::$char2order[$char_b] : 9999;
      
      return (
$order_a $order_b) ? -1;
    }
    return (
$len_a $len_b) ? -1;
  }
}

// usage example:

$t = array(
  
'Birnen''Birne''?pfel''Apfel',
);

uasort($t'utf_8_german::cmp');
echo 
'$t: <pre>'.htmlspecialchars(print_r($t,true),null,'UTF-8').'</pre>';
?>

[#2] shawn at shawnwilkerson dot com [2009-05-05 10:03:29]

I kept getting varied results using natcasesort and sort on mixed arrays -- per the descriptions.

Sometimes simple is better:

A little snippet of code:

<?php                        if($responders->num_rows) {
                            
$i=0;
                            while(
$row$responders->fetch_assoc()) {
                                
$user=getUserName($row['responderID']);
                                
$r[$i]= array("sortname"=>strtolower($user),"userName"=>$user"userID"=>$row['responderID'], "responderID"=>$row['idresponders']);
                                
$i++;
                            }
                            
sort($r);
                            
print_r($r);                            
                        }

?>


I simply created a lower cased sort field at the front of the result set and then sort by it -- which provides the expected result and leaves the actual needed fields unchanged.

For the curious:  all user information is kept completed in another database (and table) from the content database due to security reasons.  The getUser functions we have written allow us to pull only what is legally allowed without exposing anything else.

This is why a left join or something wasn't used and we have to build a pseudo result array here from both databases.

[#3] claude at schlesser dot lu [2009-01-07 00:41:32]

Here a function that will natural sort an array by keys with keys that contain special characters.

<?php
function natksort($array)
{
    
$original_keys_arr = array();
    
$original_values_arr = array();
    
$clean_keys_arr = array();

    
$i 0;
    foreach (
$array AS $key => $value)
    {
        
$original_keys_arr[$i] = $key;
        
$original_values_arr[$i] = $value;
        
$clean_keys_arr[$i] = strtr($key"???????????????????""AOUaouEEAEeeeac");
        
$i++;
    }

    
natcasesort($clean_keys_arr);

    
$result_arr = array();

    foreach (
$clean_keys_arr AS $key => $value)
    {
        
$original_key $original_keys_arr[$key];
        
$original_value $original_values_arr[$key];
        
$result_arr[$original_key] = $original_value;
    }

    return 
$result_arr;
}
?>


Hope it will be useful to somebody :)

[#4] vbAlexDOSMan at Yahoo dot com [2003-09-12 01:21:57]

Ulli at Stemmeler dot net:  I remade your function -- it's a little more compact now -- Enjoy...

function ignorecasesort(&$array) {

  
  
  for ($i = 0; $i < sizeof($array); $array[$i] = strtolower($array[$i]).$array[$i], $i++);

  
  sort($array);

  
  
  for ($i = 0; $i < sizeof($array); $i++) {
    $this = $array[$i];
    $array[$i] = substr($this, (strlen($this)/2), strlen($this));
  }
}

[#5] dslicer at maine dot rr dot com [2003-06-02 18:41:16]

Something that should probably be documented is the fact that both natsort and natcasesort maintain the key-value associations of the array. If you natsort a numerically indexed array, a for loop will not produce the sorted order; a foreach loop, however, will produce the sorted order, but the indices won't be in numeric order. If you want natsort and natcasesort to break the key-value associations, just use array_values on the sorted array, like so:

natcasesort($arr);
$arr = array_values($arr);

[#6] tmiller25 at hotmail dot com [2002-04-25 19:55:25]

add this loop to the function above if you want items which have the same first characters to be listed in a way that the shorter string comes first.
--------------------
  
  for($i=count($array)-1;$i>0;$i--) {
    $str_a = $array[$i  ];
    $str_b = $array[$i-1];
    $cmp_a = strtolower(substr($str_a,0,strlen($str_a)));
    $cmp_b = strtolower(substr($str_b,0,strlen($str_a)));
    if ($cmp_a==$cmp_b && strlen($str_a)<strlen($str_b)) {
      $array[$i]=$str_b; $array[$i-1]=$str_a; $i+=2;
    }
  }
--------------------

上一篇: 下一篇: