it-swarm.com.ru

PHP Сортировать многомерный массив по элементу, содержащему дату

У меня есть массив, такой как:

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
    )

)

Может кто-нибудь предложить способ сортировки/упорядочить это на основе элемента datetime?

92
Tim

Используйте usort() и пользовательскую функцию сравнения:

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

EDIT: Ваши данные организованы в массив массивов. Чтобы лучше их различать, давайте назовем записи внутренних массивов (данных), чтобы ваши данные действительно представляли собой массив записей.

usort будет одновременно передавать две из этих записей данной функции сравнения date_compare(). Затем date_compare извлекает поле "datetime" каждой записи как метку времени UNIX (целое число) и возвращает разницу, так что результатом будет 0, если обе даты равны, положительное число, если первая ($a) больше, или отрицательное значение, если второй аргумент ($b) больше. usort() использует эту информацию для сортировки массива.

176
Ferdinand Beyer

Это должно работать. Я преобразовал дату в Unix время через strtotime.

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

С php7 вы можете использовать оператор космического корабля :

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

http://us2.php.net/manual/en/function.array-multisort.php см. третий пример:

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

?>

к вашему сведению, использование парсера unix (секунды с 1970 года) или mysql (YmdHis - 20100526014500) будет проще для парсера, но я думаю, что в вашем случае это не имеет значения.

5
Toby

$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);
4
Ajit Kumar

Сортировка массива записей/assoc_arrays по указанному полю даты и времени mysql и по порядку:

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

Вы можете просто решить эту проблему, используя usort () с функцией обратного вызова. Нет необходимости писать какие-либо пользовательские функции.

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

Я наткнулся на этот пост, но я хотел отсортировать по времени при возврате предметов в моем классе, и я получил ошибку.

Поэтому я исследую сайт php.net и в итоге делаю это:

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

Вы можете найти очень полезные примеры на сайте PHP.net

Мой массив выглядел так:

  '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)
1
Functional Rocking

Для дат 'd/m/Y':

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

    return $t1 > $t2;
});

где $i - индекс массива

0
Borjão