PHP Ordina un array multidimensionale per elemento contenente la data


113

Ho un array come:

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
    )

)

Qualcuno può suggerire un modo per ordinare / ordinare questo in base all'elemento datetime?

Risposte:


206

Usa usort()e una funzione di confronto personalizzata:

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

EDIT : i tuoi dati sono organizzati in una matrice di array. Per distinguerli meglio, chiamiamo record di array interni (dati), in modo che i tuoi dati siano davvero un array di record.

usortpasserà due di questi record alla data funzione di confronto date_compare()alla volta. date_comparequindi estrae il "datetime"campo di ciascun record come un timestamp UNIX (un numero intero) e restituisce la differenza, in modo che il risultato sarà 0se entrambe le date sono uguali, un numero positivo se la prima ( $a) è maggiore o un valore negativo se la il secondo argomento ( $b) è più grande. usort()utilizza queste informazioni per ordinare l'array.


1
in questo esempio, $ array deve contenere gli elementi $ a e $ b? - Sto ricevendo un errore funzione di confronto non valida
— Tim

No, $ae $bmanterrà gli array all'interno $array. Assicurati di non aver scritto male il nome della funzione.
— Ferdinand Beyer

Non sono sicuro di capire. Nel mio esempio, ho 3 array nell'array - ho confermato il nome, ottenendo ancora una funzione di confronto non valida
— Tim

Vedi la spiegazione che ho aggiunto. Ho testato il codice e per me funziona bene!
— Ferdinand Beyer

9
Non conosco CodeIgniter, ma stai definendo la funzione all'interno di una classe? Quindi devi definirlo al di fuori della classe o usare un diverso argomento di callback:, in usort($array, array($this, "date_compare"))modo che usort()sappia che è una funzione / metodo di classe. Vedi anche: php.net/manual/en/…
— Ferdinand Beyer

45

Questo dovrebbe funzionare. Ho convertito la data in unix time tramite strtotime.

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

La versione a una riga utilizzerebbe più metodi di array:

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

Funziona alla grande. Basta sostituire: $ originalArray con il nome del tuo array multidimensionale. E sostituisci: "datetime" con il nome del campo del sotto-array per la data. Grazie.
— qui

1
questa soluzione sta andando bene per me. anche l'opzione di ordinamento è ottima (SORT_ASC o SORT_DESC). Molte grazie.
— Andras Barth

funziona magnificamente con un piccolo avvertimento (o quello, o sto facendo qualcosa di sbagliato) ... il campo della data che devo ordinare ha date nel formato gg / mm / aaaa o aaaa / mm / gg (con barre). In tal caso, l'ordinamento non ha funzionato per qualche motivo (ordinato solo per giorno, non per l'intera data). Ho pre-elaborato le date per convertirle in gg-mm-aaaa o aaaa-mm-gg e ha funzionato quindi grazie !!! (qualche idea sul perché funziona con i trattini ma non con le barre?)
— Javier Larroulet,

array_multisort è l'unico metodo di ordinamento che ha funzionato per ordinare il mio file json per pubdate. Grazie.
— grc

Funziona davvero bene per me, grazie
— Fernando Torres

41

Da php7 puoi usare l' operatore Spaceship :

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

6

http://us2.php.net/manual/en/function.array-multisort.php vedi terzo esempio:

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

?>

Cordiali saluti, utilizzare un unix (secondi dal 1970) o un timestamp mysql (YmdHis - 20100526014500) sarebbe più facile per il parser ma penso che nel tuo caso non faccia differenza.


5

Ordinamento dell'array di record / assoc_arrays per campo datetime mysql specificato e per ordine:

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

Totalmente quello di cui ho bisogno. Ma deve cambiare str_to_upperin 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

Puoi semplicemente risolvere questo problema usando usort () con la funzione di callback. Non è necessario scrivere alcuna funzione personalizzata.

$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

Mi sono imbattuto in questo post ma volevo ordinare in base all'ora quando ho restituito gli elementi all'interno della mia classe e ho ricevuto un errore.

Quindi cerco il sito web php.net e finisco per fare questo:

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

Puoi trovare esempi molto utili nel sito web PHP.net

Il mio array aveva questo aspetto:

  '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

Per le 'd/m/Y'date:

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

    return $t1 > $t2;
});

dov'è $il'indice dell'array


1

Per coloro che stanno ancora cercando di risolverlo in questo modo all'interno di una classe con una funzione sortByDate, vedere il codice seguente

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

    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.