Помогите сортировать ключи - PullRequest
2 голосов
/ 24 августа 2010

Мне нужна помощь в сортировке [Time] данных из этого массива в php.Для данного дня время НЕ в порядке.Есть ли способ отсортировать это?Спасибо.

Array ( [0] => Array ( )
[1] => Array (         
               [Server] => server1.name 
               [Date] => Sun Aug 22 2010         
               [Set] => db2.bak_lvm         
               [Time] => 06:00:02         
               [Duration] => 01:28:12         
               [Size] => 72.05 GB         
               [Status] => Succeeded ) 
[2] => Array ( [Server] => server1.name                
               [Date] => Sun Aug 22 2010 
               [Set] => db2.bak_lvm 
               [Time] => 00:00:03 
               [Duration] => 01:49:37 
               [Size] => 187.24 GB 
               [Status] => Succeeded ) 
[3] => Array ( [Server] => server1.name 
               [Date] => Sun Aug 22 2010 
               [Set] => db3.bak_lvm 
               [Time] => 23:00:03 
               [Status] => Unsuccessful ) 
[4] => Array ( [Server] => server1.name 
               [Date] => Sun Aug 22 2010 
               [Set] => db4.bak_lvm  
               [Time] => 04:00:03 
               [Duration] => 00:42:36 
               [Size] => 46.46 GB 
               [Status] => Succeeded ) 

Вот мой php-код на данный момент:

<?php
$data = array();
$InputFile = file("test.txt");
foreach ($InputFile as $line){
    preg_match_all("/([0-9])-([^=]+)=([^;]+);/", $line, $matches, PREG_SET_ORDER);

    $LineData = array();
    foreach ($matches as $information)
       $LineData[$information[2]] = $information[3];
       $data[] = $LineData;
}
    $keys = array('Server', 'Date','Set','Time','Duration','Size','Status');
        echo '<table id="stats"><tr>';
        foreach ($keys as $column)
           echo '<th>' . $column . '</th>';
            echo '</tr>';

        $counter=0;
        foreach ($data as $row){
           $counter ++;
           $class = $counter % 2 === 0 ? 'alt1' : 'alt2';
           echo '<tr class="' . $class . '">';

             foreach ($keys as $column)
                if (isset($row[$column])){
                  echo '<td>' . $row[$column];
                  } else {
                  echo '<td>' . '' . '</td>';
                }
        }
        echo '</table>';
        print_r($data);
?>

Обновлен : последняя сортировка после использования предложенного Биллом исправления.[Time] в порядке, но также необходимо отсортировать его в пределах [Date]

Array ( [0] => Array (
            [Server] => server1.name
            [Date] => Mon Aug 23 2010
            [Set] => db2.bak_lvm
            [Time] => 00:00:03
            [Duration] => 01:50:24
            [Size] => 187.24 GB
            [Status] => Succeeded )
    [1] => Array ( [Server] => server1.name
                   [Date] => Mon Aug 23 2010
                   [Set] => db3.bak_lvm
                   [Time] => 04:00:02
                   [Duration] => 00:42:28
                   [Size] => 46.47 GB
                   [Status] => Succeeded )
    [2] => Array ( [Server] => server1.name
                   [Date] => Sun Aug 22 2010
                   [Set] => db3.bak_lvm
                   [Time] => 04:00:03
                   [Duration] => 00:42:36
                   [Size] => 46.46 GB
                   [Status] => Succeeded )
    [3] => Array ( [Server] => server1.name
                   [Date] => Mon Aug 23 2010
                   [Set] => db1.bak_lvm
                   [Time] => 06:00:02
                   [Duration] => 01:28:24
                   [Size] => 72.05 GB
                   [Status] => Succeeded )
    [4] => Array ( [Server] => server1.name
                   [Date] => Sun Aug 22 2010
                   [Set] => db4.bak_lvm
                   [Time] => 20:00:03
                   [Duration] => 04:17:57
                   [Size] => 426.60 GB
                   [Status] => Succeeded )

Ответы [ 3 ]

2 голосов
/ 24 августа 2010

Если вы уже используете PHP5.3, вы можете использовать кучу ( руководство | wiki ) для этого:

class SortByDateTimeDescending extends SplMaxHeap
{
    public function compare($a, $b)
    {
        if(!empty($a['Date']) && !empty($a['Time']) &&
           !empty($b['Date']) && !empty($b['Time']))
        {
            $timestampA = strtotime("{$a['Date']} {$a['Time']}");
            $timestampB = strtotime("{$b['Date']} {$b['Time']}");
            return $timestampA - $timestampB;
        }
        return 0;
    }
}

$sorter = new SortByDateTimeDescending;
array_map(array($sorter, 'insert'), $data);

Затем вы можете foreach over $ sorter или, если вы хотите вернуть кучу обратно в массив, используйте

$sortedData = iterator_to_array($sorter);

Если вы еще не используете PHP5.3, вы можете использовать код в функции сравнения для usort()данные.Порядок будет изменен, хотя (имеется в виду по возрастанию).Перебирать отсортированный массив очень просто.

Вы также можете использовать SortingIterator для непосредственного просмотра массива.

2 голосов
/ 24 августа 2010

edit: Теперь, когда я лучше понимаю ваши входные данные, я протестировал этот скрипт.

Сначала я читаю файл данных, как вы, но я собираю поле данных по полю непосредственно в двумерный массив:

<?php

$data = array();
$InputFile = file("test.txt");
foreach ($InputFile as $line)
{
  preg_match_all("/([0-9])-([^=]+)=([^;]+);/", $line, $matches, PREG_SET_ORDER);

  foreach ($matches as $information)
  {
    $id = $information[1];
    $field = $information[2];
    $value = $information[3];
    $data[$id][$field] = $value;
  }
}

Далее я сортирую массив данных с пользователемопределенная функция сортировки передана в usort().Спасибо комментаторам за предложения по улучшению этой функции.

function comparebydatetime($a, $b) {
  $adate = strtotime($a["Date"]." ".$a["Time"]);
  $bdate = strtotime($b["Date"]." ".$b["Time"]);
  return $adate-$bdate;
}

usort($data, "comparebydatetime");

Теперь данные сортируются по дате и времени, поэтому я могу просто вывести их:

$keys = array("Server", "Date","Set","Time","Duration","Size","Status");
echo "<table id='stats'>\n";
echo "<tr>\n";
foreach ($keys as $column)
{
  echo "<th>" . htmlspecialchars($column) . "</th>\n";
}
echo "</tr>\n";

$counter=0;
foreach ($data as $row)
{
  $counter ++;
  $class = $counter % 2 === 0 ? "alt1" : "alt2";
  echo "<tr class='" . htmlspecialchars($class) . "'>\n";

  foreach ($keys as $column)
  {
    echo "<td>";
    if (isset($row[$column]))
    {
      echo htmlspecialchars($row[$column]);
    }
    echo "</td>\n";
  }
  echo "</tr>\n";
}
echo "</table>";

Я также добавил некоторые другие изменения для улучшения стиля PHP:

  • Будьте последовательны в отношении отступов.
  • Используйте фигурные скобки даже для блока с одним оператором.
  • Используйте htmlspecialchars() для вывода динамических данных (включая имена полей, классы CSS и т. Д.).
0 голосов
/ 24 августа 2010

Проще говоря: пройдитесь по массиву и укажите каждую дату в качестве ключа каждого дочернего элемента, а затем ksort () полученного массива. Не забудьте при необходимости перевести дату в DateTime, прежде чем устанавливать ее в качестве ключа массива, чтобы ksort () могла работать через нее:

$to_be_sorted = array();
foreach($array as $child) {
     $date = new DateTime($child["date"].' '.$child["time"]);
     $to_be_sorted[$date] = $child;
}
$sorted = ksort($to_be_sorted);

Вы потеряете свои оригинальные ключи (0,1, ..., 4), но я предполагаю, что это не проблема?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...