1

I'm reading a multi-dimensional array from JSON. I then need to sort based on two of the parameters, about 3 levels deep in the array.

I've tried array_multisort, but could only do one level at a time. I then moved to usort, based on several examples I saw here on stackoverflow, but it stubbornly refuses to work.

JSON:

    [
    {
    "multiple parameters": "foobar",
        "projects": [
            {
                "id": "00101",
                "date": "9",
                "time": "14:00",
          "duration":"30"
            },
            {
                "id": "EX001",
                "date": "8",
                "time": "13:30",
          "duration":"15"
            },
            {
                "id": "9A200",
                "date": "10",
                "time": "8:45",
          "duration":"15"
            },
            {
                "id": "EQ002",
                "date": "8",
                "time": "9:30",
          "duration":"15"
            }
        ]
    }
]

PHP:

//read data from the json file
$theschedule = '/directory/path/schedule.json';

//read json file
if (file_exists ($theschedule)){
    $contents = utf8_encode(file_get_contents($theschedule));
    $Schedule= json_decode($contents, true); 

//Sort array

usort($Schedule[0]['projects'], 'order_by_date_time');

function order_by_date_time($a, $b)
{
  if ($a['date'] == $b['date'])
  {
    // date is the same, sort by time
    if ($a['time'] == $b['time']) return 0;
    return $a['time'] == 'y' ? -1 : 1;
  }

  // sort the date first:
  return $a['date'] < $b['date'] ? 1 : -1;
}

Each meeting has a date and time - I need to sort by date, and then time, to populate a meeting schedule page.

I've read many, many stackoverflow posts. The most helpful were Sort multidimensional array by multiple criteria

Sort an associative array in php with multiple condition (source of the 'order_by_date_time' function)

I've read the PHP manual on usort at http://www.php.net/manual/en/function.usort.php (and many of the other array sort functions).

I've also validated the JSON with JSONLint, so I don't think it's the problem - but if that might be the problem, I can change it as well.

I know related questions have been raised here before - I've read so many of the posts, and tried so many of the suggested answers. There's some piece missing in my code, though, that I just can't see.

Community
  • 1
  • 1

2 Answers2

3

This should work for you.

 function order_by_date_time($a, $b){
       if ($a["date"] == $b["date"]){
            return strtotime($a["time"]) - strtotime($b["time"]);
       } 
       return $a["date"] - $b["date"];
 }

 usort ($Schedule[0]['projects'], "order_by_date_time");

See Working Fiddle

Orangepill
  • 24,500
  • 3
  • 42
  • 63
  • The strtotime looked very promising, but it still didn't sort anything. Utterly perplexed. I'm using version 5.3.3; can't think of any reason that usort would just .. not sort. – user2208757 Aug 02 '13 at 21:18
  • I don't know what magic the Fiddle has, but it works. IT WORKS!!!!! Very happy. Very confused, as I'm comparing two identical sets of code and one works and the other doesn't ... I'll find the difference eventually. But in the meantime, the happy dance. :) THANK YOU!! – user2208757 Aug 02 '13 at 21:43
0

What about looping through all meetings, and adding an additional date_time field which is a sortable combination of both fields. Then you'd only need to sort on the one.

Travis Hegner
  • 2,465
  • 1
  • 12
  • 11
  • OK. As a workaround, this is working. I'm still working out how to make the rest of the page work with the new system - when I constructed the final calendar, I use a foreach loop to go through the sorted array, and use the separate date field to generate new headings. It's not insurmountable, though - working though it now. Thanks! – user2208757 Aug 02 '13 at 21:21