web-dev-qa-db-fra.com

PHP Trier un tableau multidimensionnel par élément contenant la date

J'ai un tableau tel que:

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
    )

)

Quelqu'un peut-il suggérer un moyen de trier/ordonner ceci basé sur l'élément datetime?

92
Tim

Utilisez usort() et une fonction de comparaison personnalisée:

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

EDIT: vos données sont organisées dans un tableau de tableaux. Pour mieux les distinguer, appelons les enregistrements de tableaux internes (données) afin que vos données constituent réellement un tableau d'enregistrements.

usort transmettra deux de ces enregistrements à la fonction de comparaison donnée date_compare() à la fois. date_compare extrait ensuite le champ "datetime" de chaque enregistrement sous la forme d'un horodatage UNIX (entier) et renvoie la différence. Le résultat est donc 0 si les deux dates sont égales, un nombre positif si le premier ($a) est plus grand ou valeur négative si le deuxième argument ($b) est plus grand. usort() utilise ces informations pour trier le tableau.

176
Ferdinand Beyer

Cela devrait marcher. J'ai converti la date en heure unix via strtotime.

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

Depuis php7, vous pouvez utiliser l’opérateur Vaisseau spatial :

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 voir le troisième exemple:

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

?>

par exemple, utiliser un timestamp unix (secondes à partir de 1970) ou mysql (YmdHis - 20100526014500) serait plus facile pour l’analyseur, mais je pense que dans votre cas, cela ne fait aucune différence.

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

Tri du tableau d'enregistrements/assoc_arrays par le champ mysql datetime spécifié et par ordre:

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

Vous pouvez simplement résoudre ce problème en utilisant usort () avec la fonction de rappel. Pas besoin d'écrire une fonction personnalisée.

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

Je suis arrivé à ce poste, mais je voulais trier par ordre chronologique lors du retour des éléments dans ma classe et j'ai obtenu une erreur.

Donc, je recherche le site php.net et finis par faire ceci:

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

Vous pouvez trouver des exemples très utiles sur le site web PHP.net

Mon tableau ressemblait à ceci:

  '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

Pour les dates '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 est l'index du tableau

0
Borjão