如何在php中为人类(自然排序)排序关联数组?

时间:2013-03-24 14:58:53

标签: php sorting associative-array natural-sort

如何在php中为人类(自然排序)排序关联数组?

以下代码:

<?php

$notSorted = array( 
array( 'Title' => 'rose', 
'Price' => 1.25,
'Number' => '10' 
),
array( 'Title' => 'daisy', 
'Price' => 0.75,
'Number' => '1',
),
array( 'Title' => 'orchid', 
'Price' => 1.15,
'Number' => '7' 
)
);
     

//我打赌排序将在这里发生

foreach ( $notSorted as $val )
  echo $val['Number'], " - ";

?>

要输出: 10 - 1 - 7

如何让“数字”排序(对于人类)?喜欢: 1 - 7 - 10

此外,如果'Number'是一个int,如果它是一个字符串怎么办?

3 个答案:

答案 0 :(得分:0)

字段“Number”是字符串,所以它被char比较char而不是数千,然后是数百到数百等等。

您可以编写自己的排序功能,并将其用于usortsortSORT_NUMERICarray_multi_sort

答案 1 :(得分:0)

您可以通过这种方式尝试:

<?php

function record_sort($records, $field, $reverse=false)
 {
     $hash = array();

    foreach($records as $record)
     {
         $hash[$record[$field]] = $record;
     }

    ($reverse)? krsort($hash) : ksort($hash);

    $records = array();

    foreach($hash as $record)
     {
         $records []= $record;
     }

    return $records;
 }

// Example below

$airports = array
 (
     array( "code" => "LHR", "name" => "Heathrow" ),
     array( "code" => "LGW", "name" => "Gatwick" ),
 );

printf("Before: <pre>%s</pre>", print_r($airports, true));

$airports = record_sort($airports, "name");

printf("After: <pre>%s</pre>", print_r($airports, true));

?>

Example Outputs:

Before: Array
 (
     [0] => Array ( [code] => LHR, [name] => Heathrow )
     [1] => Array ( [code] => LGW, [name] => Gatwick )
 )

After: Array
 (
     [0] => Array ( [code] => LGW, [name] => Gatwick )
     [1] => Array ( [code] => LHR, [name] => Heathrow )
 ) 

来自http://php.net/manual/en/function.asort.php

答案 2 :(得分:0)

如果Number字段是整数(或浮点数),则可以使用array_multisort并指定要对Number字段进行排序。 http://php.net/manual/en/function.array-multisort.php文档中的示例#3向您展示了如何为关联数组执行此操作。

如果Number是一个字符串,事情就更难了 - 在这种情况下你必须做一个“自然”排序,以确保“7”在“10”之前出现。如果您使用的是PHP 5.4或更高版本,则可以将array_multisortSORT_NATURAL标志一起使用。 如果您使用的是PHP 5.4之前的版本,则可能需要使用usortstrnatcmp。有关如何执行此操作的详细信息,请参阅https://stackoverflow.com/a/11315019/26311