How to sort a JSON array with PHP

29,447

You can use usort and a custom comparison function:

$data = '{"info":[{"id":1, "title":"original title", "name":"john doe", "date":"2010-05-15"}, {"id":2, "title":"another title", "name":"foo bar", "date":"2009-04-11"}]}';

$info = json_decode($data, true)['info'];

usort($info, function ($a, $b) {
    return $a['date'] <=> $b['date'];
});

<=> works on strings here because a string comparison is also a date comparison when your dates are formatted as YYYY-MM-DD.

Then, to show the year value for an entry, you can parse the date into a DateTime and reformat it:

$date = DateTime::createFromFormat('Y-m-d', $item['date']);
$year = $date->format('Y');

Here's a demo.

Share:
29,447
xtoffer
Author by

xtoffer

Updated on July 05, 2022

Comments

  • xtoffer
    xtoffer almost 2 years

    First of all i'm a complete newbie to this, i have searched for solutions but none seem to do the trick.

    So I am trying to sort this JSON array by date but i don't really know i should tackle this, any tips in the right direction are much appreciated!

    ["info":[
    {"id":1, "title":"original title", "name":"john doe", "date":"2010-05-15"}, 
    {"id":2, "title":"another title", "name":"foo bar", "date":"2009-04-11"},
    ...
    

    So i'm getting the data like this

    $data=file_get_contents('jsondata...');
    $d=json_decode($data,true);
    

    I would like to sort the data by date, any ideas how i should approach this? Is it also possible to return the year value only? So the output would be 2009 instead of 2009-04-11?

    Thanks in advance

  • Ry-
    Ry- about 12 years
    You also don't need uasort because the keys are numeric, and ordering them maintaining the numeric keys can be incredibly confusing (in your output, 0 comes after 1).
  • cypher
    cypher about 12 years
    Yes, it does and does so because I want it to. I don't want to modify the array any more then it's necessary for no reason. What if the key is actually important?
  • Ry-
    Ry- about 12 years
    I'll bet you $50 that the OP does not want item 1 to come before item 0 in the array, especially since it wasn't associative to begin with ;)
  • cypher
    cypher about 12 years
    You can bet me whatever you want, I'm not changing indexes just because I think that I can.
  • Ry-
    Ry- about 12 years
    Sigh I don't think you understand how ridiculous having an array in that order with those keys is. But whatever.
  • cypher
    cypher about 12 years
    Does it sound more riddiculous then relying on "1 comes after 0"? That can get even more confusing.
  • Ry-
    Ry- about 12 years
    Yes, it does. I'm sorry, but look - you're arguing that relying on 1 coming after 0 is ridiculous. 1 comes after 0. It's not confusing, it's math.
  • cypher
    cypher about 12 years
    Math has nothing to do with it, we're talking about a hash map (yes, in PHP, array is an ordered hash map). In hash map, the key has no ordering meaning. Let's make a pros and cons list: + Both functions order an array. - With usort, you reindex the array for no valid reason. Now what would confuse me? I'll do echo $array[0]; //prints Foo usort($array); echo $array[0]; //prints Bar Of course, there's a case when I want to get the first element. Wait, that should be done with reset. I see no reason for changing indexes when I don't need to.
  • xtoffer
    xtoffer about 12 years
    Thank you so much for this, got it working now! Thanks for your effort to explain this! I really appreciate it
  • xtoffer
    xtoffer about 12 years
    Thank you for your feedback andreas i really appreciate it
  • Laci
    Laci almost 10 years
    @xtoffer You should accept an answer as correct so you don't just appreciate their effort to help you, but you can also help someone like me who has the same issue as you and I try to find out which answer from here is the correct one! Thank you in advance!
  • joshuahedlund
    joshuahedlund almost 6 years
    Note: As of PHP 5.2.2, DateTime objects can be compared using comparison operators, so you should just be able to return ($dA > $dB)
  • Ry-
    Ry- almost 6 years
    @joshuahedlund: usort doesn’t expect a boolean return, but you’re right, it doesn’t make much sense to compare only the year even if you only show the year.
  • user982853
    user982853 over 4 years
    Does this work on large lists? or just lists of two?
  • AbraCadaver
    AbraCadaver over 4 years
    No need to convert if they're in this format 2010-05-15