2013-12-02 5 views
1

Я пытаюсь найти способ сортировки моего массива из SimpleXMLElement. Я хотел бы отсортировать по времени начала, которое я могу получить от event_start_dt. Я также хотел бы сортировать по номеру комнаты как отдельный процесс. В настоящее время массив упорядочен по объекту (SimpleXMLElement) #. Вот var_dump ($ массив):Объект сортировки (SimpleXMLElement) php

object(SimpleXMLElement)#275 (1) { 
["reservation"]=> array(3) 
    { 
    [0]=> object(SimpleXMLElement)#287 (28) { 
     ["reservation_id"]=> string(7) "8644894" 
     ["event_start_dt"]=> string(25) "2013-12-02T12:00:00-08:00" 
     ["event_end_dt"]=> string(25) "2013-12-02T13:00:00-08:00" 
     ["event_id"]=> string(6) "314147" 
     ["event_name"]=> string(24) "Practice" 
     ["room_id"]=> string(3) "202" 
    } 
    [1]=> object(SimpleXMLElement)#288 (28) { 
     ["reservation_id"]=> string(7) "8595185" 
     ["event_start_dt"]=> string(25) "2013-12-02T08:00:00-08:00" 
     ["event_end_dt"]=> string(25) "2013-12-02T09:00:00-08:00" 
     ["event_id"]=> string(6) "314005" 
     ["event_name"]=> string(24) "Meeting" 
     ["room_id"]=> string(3) "207" 
    } 
    [2]=> object(SimpleXMLElement)#289 (28) { 
     ["reservation_id"]=> string(7) "8718654" 
     ["event_start_dt"]=> string(25) "2013-12-02T10:00:00-08:00" 
     ["event_end_dt"]=> string(25) "2013-12-02T11:00:00-08:00" 
     ["event_id"]=> string(6) "315811" 
     ["event_name"]=> string(20) "Maintenance" 
     ["room_id"]=> string(3) "202" 
    } 
} } 

Я попытался usort и asort, но не получил его на работу с любым методом.

метод usort:

function sortByTime($a, $b){ 
    $a = strtotime($array->event_start_dt); 
    $b = strtotime($array->event_start_dt); 
     if ($a==$b) return 0; 
     return ($a < $b) ?-1 : 1; 
     } 

     usort($arrTimes, 'sortByTime'); 

     var_dump($arrTimes); 

Попытка ниже код дает мне предупреждение: usort() ожидает параметр 1, чтобы быть массивом, данный объект.

foreach ($rez->reservation as $value){ 
    $var1 = $value->space_reservation->space_name; 
    $var2 = substr($value->event_start_dt,11,5); 
} 
sort_obj_arr($value,$var1,SORT_DESC); 

echo "<pre>SORTED "; 
print_r($value); 
echo "</pre>"; 

function sort_obj_arr(& $arr, $sort_field, $sort_direction) 
{ 
    $sort_func = function($obj_1, $obj_2) use ($sort_field, &$sort_direction) 
    { 
     if ($sort_direction == SORT_ASC) { 
      return strnatcasecmp($obj_1->$sort_field, $obj_2->$sort_field); 
     } else { 
      return strnatcasecmp($obj_2->$sort_field, $obj_1->$sort_field); 
     } 
    }; 
    usort($arr, $sort_func); 

} 

У меня есть массив из моего контроллера, но не может получить usort работу: я получаю либо: usort() ожидает параметр 1, чтобы быть массивом, данный объект или нуль.

$array = array($this->data); 
print_r($array); 

array(1) { 
[0]=> object(SimpleXMLElement)#280 (1) { ["reservation"]=> array(3) { 
     [0]=> object(SimpleXMLElement)#287 (28) { 
      ["reservation_id"]=> string(7) "8644894" 
      ["event_start_dt"]=> string(25) "2013-12-02T12:00:00-08:00" 
      ["event_end_dt"]=> string(25) "2013-12-02T13:00:00-08:00" 
      ["event_id"]=> string(6) "314147" 
      ["event_name"]=> string(24) "Practice" 
      ["room_id"]=> string(3) "202" 
     } 
     [1]=> object(SimpleXMLElement)#288 (28) { 
      ["reservation_id"]=> string(7) "8595185" 
      ["event_start_dt"]=> string(25) "2013-12-02T08:00:00-08:00" 
      ["event_end_dt"]=> string(25) "2013-12-02T09:00:00-08:00" 
      ["event_id"]=> string(6) "314005" 
      ["event_name"]=> string(24) "Meeting" 
      ["room_id"]=> string(3) "207" 
     } 
     [2]=> object(SimpleXMLElement)#289 (28) { 
      ["reservation_id"]=> string(7) "8718654" 
      ["event_start_dt"]=> string(25) "2013-12-02T10:00:00-08:00" 
      ["event_end_dt"]=> string(25) "2013-12-02T11:00:00-08:00" 
      ["event_id"]=> string(6) "315811" 
      ["event_name"]=> string(20) "Maintenance" 
      ["room_id"]=> string(3) "202" 
     } 
    } } 

Запрос print_r:

SimpleXMLElement Object 
(
    [reservation] => Array(3) 
     (
      [0] => SimpleXMLElement Object 
       (
        [reservation_id] => 8604174 
        [event_start_dt] => 2013-12-31T06:00:00-08:00 
        [event_end_dt] => 2013-12-31T08:00:00-08:00 
        [event_id] => 314147 
        [event_name] => Practice 
        [room_id] => 202 
       ) 
     [1] => SimpleXMLElement Object 
       (
        [reservation_id] => 8604177 
        [event_start_dt] => 2013-12-31T05:00:00-08:00 
        [event_end_dt] => 2013-12-31T06:00:00-08:00 
        [event_id] => 314150 
        [event_name] => Meeting 
        [room_id] => 216 
       ) 
     [2] => SimpleXMLElement Object 
       (
        [reservation_id] => 8604189 
        [event_start_dt] => 2013-12-31T10:00:00-08:00 
        [event_end_dt] => 2013-12-31T11:00:00-08:00 
        [event_id] => 314150 
        [event_name] => Maintenance 
        [room_id] => 220 
       ) 
) 
) 

$arrTimes = xml2array($array->reservation); 

var_dump($arrTimes) 

array(5) { 
["reservation_id"]=> string(7) "8604175" 
["event_start_dt"]=> string(25) "2014-01-02T06:00:00-08:00" 
["event_end_dt"]=> string(25) "2014-01-02T08:00:00-08:00" 
["event_id"]=> string(6) "314147" 
["event_name"]=> string(24) "Practice" 
} 
+0

usort() должен работать на отдельном массиве, что именно вы пробовали? – ThW

+1

Главное, чтобы помнить, что 'SimpleXMLElement' не является массивом, это объект (и' var_dump' очень вводит в заблуждение). Он не может быть отсортирован напрямую, поскольку он представляет собой фактическую структуру XML-файла, а не только копию его данных. – IMSoP

+0

Я добавил один из методов usort, которые я пробовал. Я не могу получить данные по $ array ['reserve'] [$ i] ['event_start_dt'], но я могу получить его по $ array-> event_start_dt. – sloga

ответ

1

Перед тем, как сортировать данные, необходимо создать массив, который содержит в качестве своих значений отдельных элементов, хочу сортировать. Из ваших отладочных выходов это несколько узлов <reservation> во входном XML, которые являются дочерними элементами элемента, представленного $array/$this->data в этих образцах (неважно, является ли это корнем документа или нет, SimpleXML не имеет объекта Document).

Ваш print_r и var_dump вывод показывает, что вы в настоящее время не имеют такой массив, только SimpleXML объект:

  • Ваш первый пример показывает var_dump($array) давая выход начало object(SimpleXMLElement)#275 (1) { - игнорировать слово array далее в, это просто как var_dump оказывает внутренних дел объекта.
  • Позже, у вас есть print_r($array); начало array(1) { - но это только потому, что вы заворачивали реальные данные в массиве одного элемента на строку выше ($array = array($this->data);) и что один элемент ($array[0]) показывает, как object(SimpleXMLElement)#280 (1) { ....

Обратите внимание, что нет необходимости идти дальше и конвертировать все внутреннее SimpleXML объектов в массивы - нужно просто список, который сортируется, содержащие элементы, которые заинтересованы в Я лично использую простой и явный foreach. для максимальной читаемости кода, хотя доступны «более умные» решения.

Как только у вас есть сортируемый список, вам нужна функция обратного вызова для usort, которая сравнивает два параметра. Попытка, которую вы сделали, находится по правильной линии, но относится к несуществующей (в этой функции) переменной $array; значения, которые вам нужно сравнить, являются аргументами функции, которые вы назвали $a и $b - в частности, вы хотите сравнить strtotime($a->event_start_dt) с strtotime($b->event_start_dt).

Вы также можете сделать функцию гораздо проще, так как следует общее заблуждение, что возвращаемое значение обратного вызова должна быть -1, 0 или 1. Фактически, это может быть любое целое число, и только значение его знака - возврат -42 будет иметь тот же эффект, что и возвращение -999, а именно размещение объекта $a до $b в результирующем массиве.

я не могу легко дать проверенную пример, потому что вы не предоставили основной XML, чтобы воспроизвести введенные данные (например, echo $this->data->asXML();), но основной подход, который я бы бы это:

+0

вот это решение! Спасибо! – sloga

+0

См. [Аналогичный вопрос/ответ здесь] (http://stackoverflow.com/q/15744106/287948) –

0

я бы просто бросить его как массив, используя эту функцию (например, функцию от php.net). Но учтите, что это не будет сортировать XML, а сортировать новый массив

/** 
* function xml2array 
* 
* This function is part of the PHP manual. 
* 
* The PHP manual text and comments are covered by the Creative Commons 
* Attribution 3.0 License, copyright (c) the PHP Documentation Group 
* 
* @author k dot antczak at livedata dot pl 
* @date 2011-04-22 06:08 UTC 
* @link http://www.php.net/manual/en/ref.simplexml.php#103617 
* @license http://www.php.net/license/index.php#doc-lic 
* @license http://creativecommons.org/licenses/by/3.0/ 
* @license CC-BY-3.0 <http://spdx.org/licenses/CC-BY-3.0> 
*/ 
function xml2array ($xmlObject, $out = array()) 
{ 
    foreach ((array) $xmlObject as $index => $node) 
    $out[$index] = (is_object ($node)) ? xml2array ($node) : $node; 

    return $out; 
} 

и передать ему XMLObject

$arrTimes = xml2array(YourSimpleXMLElement); 

, а затем использовать оригинальную функцию usort на новом массиве

function sortByTime($a, $b){ 
    $a = strtotime($a['event_start_dt']); 
    $b = strtotime($b['event_start_dt']); 
    if ($a==$b) 
     return 0; 
    return ($a < $b) ? -1 : 1; 
} 

И наконец

usort($arrTimes, 'sortByTime'); 
+0

Я не совсем понимаю это ... Я получаю «неопределенный индекс» для $ a = strtotime ($ a ['event_start_dt']); $ b = strtotime ($ b ['event_start_dt']); при изменении на $ a = strtotime ($ arrTimes ['event_start_dt']); $ b = strtotime ($ arrTimes ['event_start_dt']); Я получаю неопределенную переменную. У меня есть $ arrTimes = xml2array ($ array-> бронирование); над функцией sortByTime. – sloga

2

Использование array_multisort

  foreach ($rez->reservation as $value) 
      { 
        $dateTime[] = $value->event_start_dt; 
      } 

      array_multisort($dateTime,SORT_ASC,SORT_STRING,$rez->reservation); 
      echo "<pre>"; 
      print_r($rez->reservation); 

Проверьте это. это мой код

<?php 
     $myarray=array(
        0 => array 
         (
          'dateTime' => '2013-12-02T10:00:00-08:00', 
          'chanl1' => '20.10', 
          'chanl2' => '45.4', 
          'chanl3' => '', 
         ), 

        1 => array 
         (
          'dateTime' => '2013-12-02T11:00:00-08:00', 
          'chanl1' => '20.11', 
          'chanl2' => '45.4', 
          'chanl3' => '', 
         ), 
        2 => array 
         (
          'dateTime' => '2013-12-02T12:00:00-08:00', 
          'chanl1' => '20.12', 
          'chanl2' => '33.8', 
          'chanl3' => '', 
         ), 

        3 => array 
         (
          'dateTime' => '2013-12-02T09:00:00-08:00', 
          'chanl1' => '20.9', 
          'chanl2' => '33.9', 
          'chanl3' => '' 
         )); 

      foreach($myarray as $c=>$key) { 
        $dateTime[] = $key['dateTime'];      
      }   


     array_multisort($dateTime,SORT_ASC,SORT_STRING,$myarray); 
     echo "<pre>"; 
     print_r($myarray); 
     ?> 

Выхода:

Array 
(
    [0] => Array 
     (
      [dateTime] => 2013-12-02T09:00:00-08:00 
      [chanl1] => 20.9 
      [chanl2] => 33.9 
      [chanl3] => 
     ) 

    [1] => Array 
     (
      [dateTime] => 2013-12-02T10:00:00-08:00 
      [chanl1] => 20.10 
      [chanl2] => 45.4 
      [chanl3] => 
     ) 

    [2] => Array 
     (
      [dateTime] => 2013-12-02T11:00:00-08:00 
      [chanl1] => 20.11 
      [chanl2] => 45.4 
      [chanl3] => 
     ) 

    [3] => Array 
     (
      [dateTime] => 2013-12-02T12:00:00-08:00 
      [chanl1] => 20.12 
      [chanl2] => 33.8 
      [chanl3] => 
     ) 

) 

FIDDLE

+0

получите ошибку, применяя этот метод. Аргумент # 4 должен быть массивом или флажком сортировки в этой строке: array_multisort ($ dateTime, SORT_ASC, SORT_STRING, $ rez-> бронирование); – sloga

+0

@sloga Ваше резервирование массива или нет? Я имею в виду $ rez-> бронирование –

-1

Вы должны преобразовать frist в xml в массив, используя json encode decode

$ xml_array = json_decode (json_encode ((array) $ xml), TRUE);

u получит список массивов .... чем u может sory согласно дате, используя функцию strtotime.

Смежные вопросы