PHP Sortieren Sie ein mehrdimensionales Array nach einem Element, das das Datum enthält

113

Ich habe ein Array wie:

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
    )

)

Kann jemand eine Möglichkeit vorschlagen, dies basierend auf dem datetime-Element zu sortieren / zu ordnen?

Tim
quelle

Antworten:

205

Verwendung usort()und eine benutzerdefinierte Vergleichsfunktion:

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

BEARBEITEN : Ihre Daten sind in einem Array von Arrays organisiert. Um diese besser zu unterscheiden, rufen wir die inneren Arrays (Daten) auf, sodass Ihre Daten wirklich ein Array von Datensätzen sind.

usortÜbergibt zwei dieser Datensätze gleichzeitig an die angegebene Vergleichsfunktion date_compare(). date_compareExtrahiert dann das "datetime"Feld jedes Datensatzes als UNIX-Zeitstempel (eine Ganzzahl) und gibt die Differenz zurück, sodass das Ergebnis 0bei beiden Daten gleich ist, eine positive Zahl, wenn das erste ( $a) größer ist, oder ein negativer Wert, wenn die Das zweite Argument ( $b) ist größer. usort()verwendet diese Informationen, um das Array zu sortieren.

Ferdinand Beyer
quelle
1
Muss $ array in diesem Beispiel die Elemente $ a und $ b enthalten? - Ich bekomme einen Fehler ungültige Vergleichsfunktion
Tim
Nein, $aund $bhält die Arrays in $array. Stellen Sie sicher, dass Sie den Funktionsnamen nicht falsch geschrieben haben.
Ferdinand Beyer
Ich bin mir nicht sicher ob ich das verstehe. In meinem Beispiel habe ich 3 Arrays im Array - ich habe den Namen bestätigt und erhalte immer noch eine ungültige Vergleichsfunktion
Tim
Siehe die Erklärung, die ich hinzugefügt habe. Ich habe den Code getestet und er funktioniert gut für mich!
Ferdinand Beyer
9
Ich kenne CodeIgniter nicht, aber definieren Sie die Funktion innerhalb einer Klasse? Dann müssen Sie es entweder außerhalb der Klasse definieren oder ein anderes Rückrufargument verwenden : usort($array, array($this, "date_compare")), damit Sie usort()wissen , dass es sich um eine Klassenfunktion / -methode handelt. Siehe auch: php.net/manual/en/…
Ferdinand Beyer
44

Das sollte funktionieren. Ich habe das Datum über strtotime in Unix-Zeit konvertiert.

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

Eine einzeilige Version würde mehrere Array-Methoden verwenden:

array_multisort(array_map('strtotime',array_column($originalArray,'datetime')),
                SORT_DESC, 
                $originalArray);
Dave Keine
quelle
Das funktioniert super. Ersetzen Sie einfach: $ originalArray durch den Namen Ihres mehrdimensionalen Arrays. Und ersetzen Sie: 'datetime' durch den Namen Ihres Sub-Array-Felds für Datum. Vielen Dank.
Washere
1
Diese Lösung ist gut für mich. Die Sortieroption ist ebenfalls großartig (SORT_ASC oder SORT_DESC). Vielen Dank.
Andras Barth
funktioniert wunderbar mit einer kleinen Einschränkung (entweder das oder ich mache etwas falsch) ... das Datumsfeld, nach dem ich sortieren muss, hat Datumsangaben im Format TT / MM / JJJJ oder JJJJ / MM / TT (mit Schrägstrichen). In diesem Fall funktionierte die Sortierung aus irgendeinem Grund nicht (nur nach Tag sortiert, nicht nach dem gesamten Datum). Ich habe Daten vorverarbeitet, um sie entweder in TT-MM-JJJJ oder JJJJ-MM-TT umzuwandeln, und es hat funktioniert, danke !!! (
Irgendwelche
array_multisort ist die einzige Sortiermethode, mit der meine JSON-Datei nach Pubdate sortiert werden konnte. Vielen Dank.
grc
Ich arbeite sehr gut für mich, danke
Fernando Torres
41

Ab PHP7 können Sie den Raumschiff-Operator verwenden :

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

http://us2.php.net/manual/en/function.array-multisort.php siehe drittes Beispiel:

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

?>

Zu Ihrer Information, die Verwendung eines Unix (Sekunden ab 1970) oder eines MySQL-Zeitstempels (YmdHis - 20100526014500) wäre für den Parser einfacher, aber ich denke, in Ihrem Fall macht es keinen Unterschied.

Toby
quelle
5

Sortieren des Arrays von Datensätzen / assoc_arrays nach dem angegebenen MySQL-Datum / Uhrzeit-Feld und nach Reihenfolge:

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));
falko
quelle
Total was ich brauche. Muss aber ändern str_to_upperzu strtoupper.
Jimmy Adaro
4

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

Sie können dieses Problem einfach mit usort () mit Rückruffunktion lösen . Sie müssen keine benutzerdefinierte Funktion schreiben.

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

Ich bin auf diesen Beitrag gestoßen, wollte aber bei der Rückgabe der Artikel in meiner Klasse nach Zeit sortieren und habe eine Fehlermeldung erhalten.

Also recherchiere ich auf der php.net-Website und mache am Ende Folgendes:

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

Sie finden sehr nützliche Beispiele auf der PHP.net-Website

Mein Array sah folgendermaßen aus:

  '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)
Unveränderlicher Ziegel
quelle
1

Für 'd/m/Y'Daten:

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

    return $t1 > $t2;
});

Wo $iist der Array-Index?

Borjovsky
quelle
0

Für diejenigen, die in einer Klasse mit der Funktion sortByDate noch auf diese Weise eine Lösung suchen, siehe den folgenden Code

<?php

class ContactsController 
{
    public function __construct()
    {
    //
    }


    function sortByDate($key)
    {
        return function ($a, $b) use ($key) {
            $t1 = strtotime($a[$key]);
            $t2 = strtotime($b[$key]);
            return $t2-$t1;
        };

    }

    public function index()
    {

        $data[] = array('contact' => '434343434', 'name' => 'dickson','updated_at' =>'2020-06-11 12:38:23','created_at' =>'2020-06-11 12:38:23');
        $data[] = array('contact' => '434343434', 'name' => 'dickson','updated_at' =>'2020-06-16 12:38:23','created_at' =>'2020-06-10 12:38:23');
        $data[] = array('contact' => '434343434', 'name' => 'dickson','updated_at' =>'2020-06-7 12:38:23','created_at' =>'2020-06-9 12:38:23');


        usort($data, $this->sortByDate('updated_at'));

        //usort($data, $this->sortByDate('created_at'));
        echo $data;

    }
}
Dickson Godwin
quelle