How to sort this php array?

Asked

Viewed 1,683 times

4

I have this array:

$res = array();
$res[] = array("16/08/2013", "13:32", "ROBERTO");
$res[] = array("16/08/2013", "13:16", "AMANDA");
$res[] = array("14/08/2013", "12:36", "SILMARA");
$res[] = array("14/08/2013", "", "ROBERTO");
$res[] = array("14/08/2013", "", "KATIA");
$res[] = array("13/10/2015", "16:47", "ROBERTO");
$res[] = array("14/08/2013", "", "SILMARA");
$res[] = array("14/08/2013", "", "AMANDA");

I need to sort by date and time, I am using the Sort($res) but does not order as needed. The blank time must come first according to the date.

  • 1

    The first problem is the date format you are using. Code date is desirable in YYYYMMDD format, and DD/MM/YYYY only for display. You can do what you want, but you will have to operate strings to fix these "dates" (actually they are mere strings) when ordering. Important to say in the question whether the missing hours will be first or last in the ordering.

  • This array is a Result of a Webservice I can’t handle it at the source, I would have to recreate the entire local array, which is sometimes complex, more than 3 levels merged.

  • I posted the solution for the desired format, a functional demonstration and a brief explanation of how the string was rearranged. Perhaps it was the lack of whim of the webservice staff (but there may be some legitimate reason in rare cases, I can’t say it was certainly a failure). Any questions, ask I complement.

2 answers

6


The solution is to use the function usort or uasort, who use a callback to use specific sorting rules:

usort( $res, 'compara' );
uasort( $res, 'compara' );

In the above case, we are saying that who defines the order is the function compara.

The basic difference between the two is that uasort preserves the original indexes, and usort nay.

The function whose name is passed on usort or uasort is called successively with two items of the array original for once, and you must return 0, a negative number or positive number in the event of a tie, in order or out of order respectively.

In turn, within the function compara() let’s fix the order of your "date" and concatenate with time, and then return the comparison between the resulting strings using strcmp, who rightly returns 0, +n and -n as desired:

function compara( $a1, $a2 ) {
    $ts1 = substr($a1[0],6,4).substr($a1[0],3,2).substr($a1[0],0,2).$a1[1];
    $ts2 = substr($a2[0],6,4).substr($a2[0],3,2).substr($a2[0],0,2).$a2[1];
    return strcmp($ts1, $ts2);
}

See working with uasort in the IDEONE.
Compare with usort, also in the IDEONE.


Just to further detail the above function, see how the strings are mounted:

item [0]                  14/08/2013
posição                   0123456789
quantidade de caracteres  2c 2c 4c
item [1]                  12:36
item [2]                  SILMARA 


 substr($a1[0],6,4) . substr($a1[0],3,2) . substr($a1[0],0,2) . $a1[1]
 └───── ANO ──────┘   └───── MÊS ──────┘   └───── DIA ──────┘  └ HORA ┘
└────────────────────────── Item 0 ──────────────────────────┘└ Item 1 ┘

Resultado                 2013081412:36


Manual for PHP:

  • cabuloso huh :D

  • @Wallacemaxters usually have the temptation to convert into a real team, but it’s much more efficient with string, although the code doesn’t look like the most beautiful thing in the universe (although it was pretty dry until) :)

  • @Bacco Patrão your array is misordering the dates 14/16/13 !

  • 1

    @Bacco Tá eerado Naum is more than right, wrong to me... Malz ae... Another pro topic making off ;)

  • Now you realize that the year changes right :P

  • @Bacco understood yes, I am his student... I got my answer tmb... "Invincibility lies in defense, vulnerability is revealed in attack." Suntzu I felt vulnerable. But it’s over now...;)

  • 1

    Besides the good answer I will give +1 only by └ Item 1 ┘ :D

  • But I think a preg_match would be better there in :P

Show 3 more comments

4

I’m a little late, but you can do it like this: Using array_multisort

<?php
//array
$res = array();
$res[] = array("16/08/2013", "13:32", "ROBERTO");
$res[] = array("30/01/2011", "13:16", "AMANDA");
$res[] = array("14/07/2016", "12:36", "SILMARA");
$res[] = array("14/05/2013", "", "ROBERTO");
$res[] = array("14/09/2013", "", "KATIA");
$res[] = array("13/10/2015", "16:47", "ROBERTO");
$res[] = array("14/08/2013", "", "SILMARA");
$res[] = array("14/08/2011", "", "AMANDA");

//percorre as chaves e valores
foreach ($res as $key => $row) {
$ndata[$key] = $row[0];
//Inverte a data
$ndata[$key] = implode("/",array_reverse(explode("/",$ndata[$key])));
$hora[$key] = $row[1];
}
//ordena
array_multisort($ndata, SORT_DESC, $hora, SORT_ASC,$res);

//saída
echo"<pre>";
var_dump ($res);
echo"</pre>";
?>

Exit

array(8) {
[0]=>
array(3) {
[0]=>
string(10) "14/07/2016"
[1]=>
string(5) "12:36"
[2]=>
string(7) "SILMARA"
}
[1]=>
array(3) {
[0]=>
string(10) "13/10/2015"
[1]=>
string(5) "16:47"
[2]=>
string(7) "ROBERTO"
}
[2]=>
array(3) {
[0]=>
string(10) "14/09/2013"
[1]=>
string(0) ""
[2]=>
string(5) "KATIA"
}
[3]=>
array(3) {
[0]=>
string(10) "16/08/2013"
[1]=>
string(5) "13:32"
[2]=>
string(7) "ROBERTO"
}
[4]=>
array(3) {
[0]=>
string(10) "14/08/2013"
[1]=>
string(0) ""
[2]=>
string(7) "SILMARA"
}
[5]=>
array(3) {
[0]=>
string(10) "14/05/2013"
[1]=>
string(0) ""
[2]=>
string(7) "ROBERTO"
}
[6]=>
array(3) {
[0]=>
string(10) "14/08/2011"
[1]=>
string(0) ""
[2]=>
string(6) "AMANDA"
}
[7]=>
array(3) {
[0]=>
string(10) "30/01/2011"
[1]=>
string(5) "13:16"
[2]=>
string(6) "AMANDA"
}
}

Is that right? Now it’s right...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.