我将CSV数据加载到多维数组中。这样,每个“行”就是一条记录,每个“列”包含相同类型的数据。我正在使用下面的函数来加载我的CSV文件。
function f_parse_csv($file, $longest, $delimiter)
{
$mdarray = array();
$file = fopen($file, "r");
while ($line = fgetcsv($file, $longest, $delimiter))
{
array_push($mdarray, $line);
}
fclose($file);
return $mdarray;
}
我需要能够指定一个列来排序,以便它重新排列行。其中一列包含Y-m-d H:i:s格式的日期信息,我希望能够以最近的日期作为第一行进行排序。
使用闭包进行多行排序
下面是使用uasort()和匿名回调函数(闭包)的另一种方法。我经常使用这个函数。需要PHP 5.3 -没有更多的依赖!
/**
* Sorting array of associative arrays - multiple row sorting using a closure.
* See also: http://the-art-of-web.com/php/sortarray/
*
* @param array $data input-array
* @param string|array $fields array-keys
* @license Public Domain
* @return array
*/
function sortArray( $data, $field ) {
$field = (array) $field;
uasort( $data, function($a, $b) use($field) {
$retval = 0;
foreach( $field as $fieldname ) {
if( $retval == 0 ) $retval = strnatcmp( $a[$fieldname], $b[$fieldname] );
}
return $retval;
} );
return $data;
}
/* example */
$data = array(
array( "firstname" => "Mary", "lastname" => "Johnson", "age" => 25 ),
array( "firstname" => "Amanda", "lastname" => "Miller", "age" => 18 ),
array( "firstname" => "James", "lastname" => "Brown", "age" => 31 ),
array( "firstname" => "Patricia", "lastname" => "Williams", "age" => 7 ),
array( "firstname" => "Michael", "lastname" => "Davis", "age" => 43 ),
array( "firstname" => "Sarah", "lastname" => "Miller", "age" => 24 ),
array( "firstname" => "Patrick", "lastname" => "Miller", "age" => 27 )
);
$data = sortArray( $data, 'age' );
$data = sortArray( $data, array( 'lastname', 'firstname' ) );
我知道这个问题提出和回答已经有两年了,但这是另一个对二维数组排序的函数。它接受可变数量的参数,允许您传入多个键(即列名)进行排序。需要PHP 5.3。
function sort_multi_array ($array, $key)
{
$keys = array();
for ($i=1;$i<func_num_args();$i++) {
$keys[$i-1] = func_get_arg($i);
}
// create a custom search function to pass to usort
$func = function ($a, $b) use ($keys) {
for ($i=0;$i<count($keys);$i++) {
if ($a[$keys[$i]] != $b[$keys[$i]]) {
return ($a[$keys[$i]] < $b[$keys[$i]]) ? -1 : 1;
}
}
return 0;
};
usort($array, $func);
return $array;
}
试试这里:http://www.exorithm.com/algorithm/view/sort_multi_array
的作用。这里有一个通用的解决方案,你可以使用不同的列:
class TableSorter {
protected $column;
function __construct($column) {
$this->column = $column;
}
function sort($table) {
usort($table, array($this, 'compare'));
return $table;
}
function compare($a, $b) {
if ($a[$this->column] == $b[$this->column]) {
return 0;
}
return ($a[$this->column] < $b[$this->column]) ? -1 : 1;
}
}
按第一列排序:
$sorter = new TableSorter(0); // sort by first column
$mdarray = $sorter->sort($mdarray);
下面是一个php4/php5类,它将对一个或多个字段进行排序:
// a sorter class
// php4 and php5 compatible
class Sorter {
var $sort_fields;
var $backwards = false;
var $numeric = false;
function sort() {
$args = func_get_args();
$array = $args[0];
if (!$array) return array();
$this->sort_fields = array_slice($args, 1);
if (!$this->sort_fields) return $array();
if ($this->numeric) {
usort($array, array($this, 'numericCompare'));
} else {
usort($array, array($this, 'stringCompare'));
}
return $array;
}
function numericCompare($a, $b) {
foreach($this->sort_fields as $sort_field) {
if ($a[$sort_field] == $b[$sort_field]) {
continue;
}
return ($a[$sort_field] < $b[$sort_field]) ? ($this->backwards ? 1 : -1) : ($this->backwards ? -1 : 1);
}
return 0;
}
function stringCompare($a, $b) {
foreach($this->sort_fields as $sort_field) {
$cmp_result = strcasecmp($a[$sort_field], $b[$sort_field]);
if ($cmp_result == 0) continue;
return ($this->backwards ? -$cmp_result : $cmp_result);
}
return 0;
}
}
/////////////////////
// usage examples
// some starting data
$start_data = array(
array('first_name' => 'John', 'last_name' => 'Smith', 'age' => 10),
array('first_name' => 'Joe', 'last_name' => 'Smith', 'age' => 11),
array('first_name' => 'Jake', 'last_name' => 'Xample', 'age' => 9),
);
// sort by last_name, then first_name
$sorter = new Sorter();
print_r($sorter->sort($start_data, 'last_name', 'first_name'));
// sort by first_name, then last_name
$sorter = new Sorter();
print_r($sorter->sort($start_data, 'first_name', 'last_name'));
// sort by last_name, then first_name (backwards)
$sorter = new Sorter();
$sorter->backwards = true;
print_r($sorter->sort($start_data, 'last_name', 'first_name'));
// sort numerically by age
$sorter = new Sorter();
$sorter->numeric = true;
print_r($sorter->sort($start_data, 'age'));
你可以使用array_multisort()
试试这样做:
foreach ($mdarray as $key => $row) {
// replace 0 with the field's index/key
$dates[$key] = $row[0];
}
array_multisort($dates, SORT_DESC, $mdarray);
对于PHP >= 5.5.0,只需提取要排序的列。不需要循环:
array_multisort(array_column($mdarray, 0), SORT_DESC, $mdarray);