PHP Sort a multidimensional array by element conta

2018-12-31 13:44发布

问题:

I have an array such as:

Array
(
[0] => Array
    (
        [id] => 2
        [type] => comment
        [text] => hey
        [datetime] => 2010-05-15 11:29:45
    )

[1] => Array
    (
        [id] => 3
        [type] => status
        [text] => oi
        [datetime] => 2010-05-26 15:59:53
    )

[2] => Array
    (
        [id] => 4
        [type] => status
        [text] => yeww
        [datetime] => 2010-05-26 16:04:24
    )

)

Can anyone suggest a way to sort/order this based on the datetime element?

回答1:

Use usort() and a custom comparison function:

function date_compare($a, $b)
{
    $t1 = strtotime($a[\'datetime\']);
    $t2 = strtotime($b[\'datetime\']);
    return $t1 - $t2;
}    
usort($array, \'date_compare\');

EDIT: Your data is organized in an array of arrays. To better distinguish those, let\'s call the inner arrays (data) records, so that your data really is an array of records.

usort will pass two of these records to the given comparison function date_compare() at a a time. date_compare then extracts the \"datetime\" field of each record as a UNIX timestamp (an integer), and returns the difference, so that the result will be 0 if both dates are equal, a positive number if the first one ($a) is larger or a negative value if the second argument ($b) is larger. usort() uses this information to sort the array.



回答2:

From php7 you can use the Spaceship operator:

usort($array, function($a, $b) {
  return new DateTime($a[\'datetime\']) <=> new DateTime($b[\'datetime\']);
});


回答3:

This should work. I converted the date to unix time via strtotime.

  foreach ($originalArray as $key => $part) {
       $sort[$key] = strtotime($part[\'datetime\']);
  }
  array_multisort($sort, SORT_DESC, $originalArray);


回答4:

http://us2.php.net/manual/en/function.array-multisort.php see third example:

<?php

$data[] = array(\'volume\' => 67, \'edition\' => 2);
$data[] = array(\'volume\' => 86, \'edition\' => 1);
$data[] = array(\'volume\' => 85, \'edition\' => 6);
$data[] = array(\'volume\' => 98, \'edition\' => 2);
$data[] = array(\'volume\' => 86, \'edition\' => 6);
$data[] = array(\'volume\' => 67, \'edition\' => 7);

foreach ($data as $key => $row) {
    $volume[$key]  = $row[\'volume\'];
    $edition[$key] = $row[\'edition\'];
}

array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);

?>

fyi, using a unix (seconds from 1970) or mysql timestamp (YmdHis - 20100526014500) would be be easier for the parser but i think in your case it makes no difference.



回答5:

$array = Array
(
  [0] => Array
   (
    [id] => 2
    [type] => comment
    [text] => hey
    [datetime] => 2010-05-15 11:29:45
   )

 [1] => Array
  (
    [id] => 3
    [type] => status
    [text] => oi
    [datetime] => 2010-05-26 15:59:53
  )

  [2] => Array
   (
    [id] => 4
    [type] => status
    [text] => yeww
    [datetime] => 2010-05-26 16:04:24
   )

   );
   print_r($array);   
   $name = \'datetime\';
   usort($array, function ($a, $b) use(&$name){
      return $a[$name] - $b[$name];});

   print_r($array);


回答6:

Sorting array of records/assoc_arrays by specified mysql datetime field and by order:

function build_sorter($key, $dir=\'ASC\') {
    return function ($a, $b) use ($key, $dir) {
        $t1 = strtotime(is_array($a) ? $a[$key] : $a->$key);
        $t2 = strtotime(is_array($b) ? $b[$key] : $b->$key);
        if ($t1 == $t2) return 0;
        return (strtoupper($dir) == \'ASC\' ? ($t1 < $t2) : ($t1 > $t2)) ? -1 : 1;
    };
}


// $sort - key or property name 
// $dir - ASC/DESC sort order or empty
usort($arr, build_sorter($sort, $dir));


回答7:

I came across to this post but I wanted to sort by time when returning the items inside my class and I got an error.

So I research the php.net website and end up doing this:

class MyClass {
   public function getItems(){
      usort( $this->items, array(\"MyClass\", \"sortByTime\") );
      return $this->items;
   }
   public function sortByTime($a, $b){
      return $b[\"time\"] - $a[\"time\"];
   }
}

You can find very useful examples in the PHP.net website

My array looked like this:

  \'recent\' => 
    array
      92 => 
        array
          \'id\' => string \'92\' (length=2)
          \'quantity\' => string \'1\' (length=1)
          \'time\' => string \'1396514041\' (length=10)
      52 => 
        array
          \'id\' => string \'52\' (length=2)
          \'quantity\' => string \'8\' (length=1)
          \'time\' => string \'1396514838\' (length=10)
      22 => 
        array
          \'id\' => string \'22\' (length=2)
          \'quantity\' => string \'1\' (length=1)
          \'time\' => string \'1396514871\' (length=10)
      81 => 
        array
          \'id\' => string \'81\' (length=2)
          \'quantity\' => string \'2\' (length=1)
          \'time\' => string \'1396514988\' (length=10)


回答8:

You can simply solve this problem using usort() with callback function. No need to write any custom function.

$your_date_field_name = \'datetime\';
usort($your_given_array_name, function ($a, $b) use (&$name) {
    return strtotime($a[$name]) - strtotime($b[$name]);
});


回答9:

For \'d/m/Y\' dates:

usort($array, function ($a, $b, $i = \'datetime\') { 
    $t1 = strtotime(str_replace(\'/\', \'-\', $a[$i]));
    $t2 = strtotime(str_replace(\'/\', \'-\', $b[$i]));

    return $t1 > $t2;
});

where $i is the array index