Как отсортировать данные JSON с помощью PHP и usort? - PullRequest
1 голос
/ 14 июня 2011

Как мне отсортировать следующее с помощью PHP?(где wed_2_open следует после wed_1_close)

У меня есть следующие данные JSON:

"hours": {
  "mon_1_open": 406800,
  "mon_1_close": 437400,
  "tue_1_open": 493200,
  "tue_1_close": 523800,
  "wed_1_open": 579600,
  "wed_1_close": 590400,
  "thu_1_open": 61200,
  "thu_1_close": 91800,
  "fri_1_open": 147600,
  "fri_1_close": 178200,
  "sat_1_open": 237600,
  "sat_1_close": 264600,
  "sun_1_open": 324000,
  "sun_1_close": 345600,
  "wed_2_open": 597600,
  "wed_2_close": 619200
}

, которые я затем преобразовываю в пригодный для использования формат, используя JSON_decode:

$obj=json_decode($json);

Thisпомещается в цикл для использования преобразования его в HTML:

foreach ($obj->hours as $key => $val) {
    // Turn array items into HTML list items
}

Из предыдущих ответов кажется, что usort может быть ответом, но я получаю ошибки, сообщающие, что $ obj является объектома не массив.

Спасибо.

Ответы [ 3 ]

4 голосов
/ 14 июня 2011

Несколько заметок:

  1. Чтобы использовать любую функцию массива для данных json_decode() ed, вы должны передать true в качестве второго параметра, который дает вам ассоциативный массив вместо объекта.

  2. Всякий раз, когда вы планируете сортировать массив, посмотрите на эту страницу , которая поможет вам решить, какую из 12+ функций сортировки массива вы должны использовать.

Поскольку желаемая сортировка не является интуитивно понятной (сортировка по ключу ставит пятницу сверху и закрывается перед открытием), вам следует определить пользовательскую функцию сортировки; используйте uksort(), что позволяет вам делать это только с ключами массива:

<?php
$data = json_decode('{"hours": {
    "mon_1_open": 406800,
    "mon_1_close": 437400,
    "tue_1_open": 493200,
    "tue_1_close": 523800,
    "wed_1_open": 579600,
    "wed_1_close": 590400,
    "thu_1_open": 61200,
    "thu_1_close": 91800,
    "fri_1_open": 147600,
    "fri_1_close": 178200,
    "sat_1_open": 237600,
    "sat_1_close": 264600,
    "sun_1_open": 324000,
    "sun_1_close": 345600,
    "wed_2_open": 597600,
    "wed_2_close": 619200
}}', true);

echo 'BEFORE ================================' . PHP_EOL;
print_r($data);

uksort($data['hours'], 'customsort'); 

echo 'AFTER  ================================' . PHP_EOL;
print_r($data);

function customsort($a, $b) {
    $tr_prefix = array(
        'mon' => 1,
        'tue' => 2,
        'wed' => 3,
        'thu' => 4,
        'fri' => 5,
        'sat' => 6,
        'sun' => 7
    );
    $tr_suffix = array(
        'open'  => 1,
        'close' => 2
    );
    $a = strtr(strtr($a, $tr_prefix), $tr_suffix);
    $b = strtr(strtr($b, $tr_prefix), $tr_suffix);
    return strcmp($a, $b);
}

Примечание: моя реализация customsort, показанная выше, является наивной. Импровизируйте при необходимости.

3 голосов
/ 14 июня 2011
$array = $json_decode($json,true);  //> tradyblix
ksort($array);                      //> Sort by keys
2 голосов
/ 14 июня 2011

Во-первых, ваш json недействителен, поскольку вы не ставите фигурные скобки вокруг ассоциативного массива, который содержит «часы».Это может не быть проблемой, если вы вырезали его для краткости, но мне пришлось изменить его при отладке.

Что более важно, вы можете попросить json_decode преобразовать данные в ассоциативный массив вместоэкземпляр stdClass . ksort позволит вам сортировать по ключам.

$json = file_get_contents('jsonsort.txt');
$obj = json_decode($json, true);

var_dump($obj);
ksort($obj['hours']);
var_dump($obj);

Вы можете отсортировать по значениям с помощью sort - usort не требуется, если вам не нужно сделатьпользовательская функция сравнения, скажем, сравнения экземпляров объектов.

Затем вы можете выполнять итерации и генерации с этим (добавлены экранирование и разметка):

echo "<ol>\n";
foreach($obj['hours'] as $key => $val) {
        echo "\t<li>" . htmlentities($key) . ' => ' . htmlentities($val) . "</li>\n";
}
echo "</ol>\n";
...