134 votes

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 ces données sur la base de l'élément datetime ?

232voto

Ferdinand Beyer Points 27723

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 tableaux intérieurs (de données) des enregistrements, de sorte que vos données soient réellement un tableau d'enregistrements.

usort passera deux de ces enregistrements à la fonction de comparaison donnée date_compare() à la fois. date_compare puis extrait le "datetime" de chaque enregistrement sous la forme d'un horodatage UNIX (un nombre entier), et renvoie la différence, de sorte que le résultat sera le suivant 0 si les deux dates sont égales, un nombre positif si la première ( $a ) est plus grand ou une valeur négative si le deuxième argument ( $b ) est plus importante. usort() utilise cette information pour trier le tableau.

1 votes

Dans cet exemple, $array doit-il contenir les éléments $a et $b ? - Je reçois une erreur de fonction de comparaison invalide.

0 votes

Non, $a et $b contiendra les tableaux dans $array . Assurez-vous que vous n'avez pas mal orthographié le nom de la fonction.

0 votes

Je ne suis pas sûr de comprendre. Dans mon exemple, j'ai 3 tableaux dans le tableau - j'ai confirmé le nom, mais j'obtiens toujours une fonction de comparaison invalide.

58voto

Dave None Points 57

Cela devrait fonctionner. 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);

Une version plus simple consisterait à utiliser plusieurs méthodes de tableau :

array_multisort(array_map('strtotime',array_column($originalArray,'datetime')),
                SORT_DESC, 
                $originalArray);

1 votes

Cela fonctionne très bien. Remplacez simplement : $originalArray par le nom de votre tableau multidimensionnel. Et remplacez : 'datetime' par le nom du champ de votre sous tableau pour la date. Merci.

1 votes

Cette solution me convient parfaitement. L'option de tri est également excellente (SORT_ASC ou SORT_DESC). Merci beaucoup.

0 votes

Fonctionne à merveille, à une petite réserve près (soit ça, soit je fais quelque chose de mal)... le champ de date sur lequel je dois effectuer le tri a des dates au format jj/mm/aaaa ou aaaa/mm/jj (avec des barres obliques). Dans ce cas, le tri n'a pas fonctionné pour une raison quelconque (trié uniquement par le jour, pas par la date entière). J'ai prétraité les dates pour les convertir en dd-mm-yyyy ou yyyy-mm-dd et cela a fonctionné, alors merci !!! (une idée sur la raison pour laquelle cela fonctionne avec des traits d'union mais pas avec des barres obliques ?)

7voto

Tobias Points 554

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

?>

Pour info, 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.

5voto

falko Points 519

Tri d'un 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));

0 votes

Tout à fait ce dont j'ai besoin. Mais doit changer str_to_upper à strtoupper .

2voto

Angelo Moreira Points 145

Je suis tombé sur ce post mais je voulais trier par heure en retournant les éléments dans ma classe et j'ai eu une erreur.

J'ai donc fait des recherches sur le site php.net et j'ai fini 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 dans le Site web de PHP.net

Mon tableau ressemblait à ça :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X