如何在PHP中对多维数组进行排序

时间:2020-03-06 14:23:25  来源:igfitidea点击:

我已将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",我希望能够以最新日期作为第一行进行排序。

解决方案

" Usort"功能就是答案。
http://php.net/usort

随着usort。这是一个通用解决方案,可用于不同的列:

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);

我更喜欢使用array_multisort。请参阅说明文件
这里。

我们可以使用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);

这是一个将对一个或者多个字段进行排序的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'));

在运行TableSorter类之前,我想出了一个基于Shinhan提供的功能的函数。

function sort2d_bycolumn($array, $column, $method, $has_header)
  {
  if ($has_header)  $header = array_shift($array);
  foreach ($array as $key => $row) {
    $narray[$key]  = $row[$column]; 
    }
  array_multisort($narray, $method, $array);
  if ($has_header) array_unshift($array, $header);
  return $array;
  }
  • $ array是要排序的MD数组。
  • $ column是我们希望排序的列。
  • $ method是我们希望如何执行排序的方式,例如SORT_DESC
  • 如果第一行包含不需要排序的标题值,则$ has_header设置为true。

我知道距此问题的答案已经两年了,但这是对二维数组进行排序的另一个函数。它接受可变数量的参数,使我们可以传递多个键(即列名)作为排序依据。需要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