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?

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.


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

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


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.


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

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

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

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)

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?


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;

    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.