Есть ли в PHP способ циклически проходить запрос и организовывать его в определенный столбец на основе значения? - PullRequest
4 голосов
/ 03 апреля 2019

Я использую Laravel и пытаюсь заполнить таблицу HTML из запроса. Таблица из базы данных содержит столбцы, среди прочего, id, user и shift. В нем около 100 записей, а в столбце shift будет стоять буква A, B, C или D. Я хочу вывести его в одну таблицу HTML, чтобы при цикле первый столбец в выходной таблице содержал только записи с A для этого значения, второй B и т. Д.

Вот мой запрос:

Shift::orderBy('shift', 'ASC')
        ->get();

Это, конечно, сортирует по алфавиту, а затем, когда я повторяю цикл, используя это:

      ...
  <tbody>
    @foreach ($shifts as $shift)
          <tr>
              <td>{{ $shift->id }}</td>
            ...
           </tr>
      @endforeach
   </tbody>
  ...

Или аналогичные варианты, из которых я пробовал много, он будет проходить через все записи с A и создавать эти ячейки / строки в таблице, а затем начинаться с B. Но к тому времени, поскольку они уже созданы, записи B начинаются, как бы там ни было много записей A.

Я просмотрел его и создал четыре отдельные таблицы, но я бы предпочел, чтобы они были в одной. Я хочу экспортировать таблицу с помощью Laravel Excel, и если они являются отдельными таблицами, они просто складываются, но я хочу, чтобы они были рядом. В любом случае, вот что я имею в виду и хочу (строки с буквами будут другой информацией в итоговой таблице):

enter image description here

Что мне не хватает? Я чувствую, что не делаю что-то очень простое. Спасибо за любую помощь.

Ответы [ 3 ]

1 голос
/ 03 апреля 2019

Я бы сказал, что наиболее эффективный способ добиться этого - выполнить сортировку на уровне БД. Для этого вы должны использовать метод orderBy(). Также хороший подход будет иметь возможность для этого.

public function scopeOrderByShiftsAsc($query)
{
    return $query->orderBy('shifts', 'asc')->orderBy('created_at', 'desc');
}

// then in your controller
public function index()
{
    $users = \App\User::orderByShiftsAsc()->get();
}

Вы можете использовать этот способ (orderBy()) либо в построителе запросов, либо в цепочке методов eloquent. Области запросов .

1 голос
/ 04 апреля 2019

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

Shift::get()->keyBy('shift')->toArray();

Вы получаете структуру, похожую на следующую:

$data = [
  "A" = [
    ['id' => 1, 'shift' => 'A'],
    ...
  ],
  "B" = [
    ['id' => 2, 'shift' => 'B'],
    ...
  ],
  ...
]

Далее вы можете перебрать наибольшую букву и создать желаемую структуру вывода:

$letters = array_keys($data)
$maxLength = 0
foreach($letters as $letter) {
  $len = count($data[$letter]);
  if ($len > $maxLength) $maxLength = $len;
}
$output = []
for($i = 0; $i < $maxLength: $i++) {
   $newRow = [];
   foreach($letters as $letter) {
     if (isset($data[$letter][$i])) {
       $newRow[$letter] = $data[$letter][$i]['id'];
     } else {
       $newRow[$letter] = '';
     }
   }
   $output[] = $newRow;
}

Затем вы можете просто передать вывод в blade-файл и создать таблицу как:

@foreach ($output as $row)
      <tr>
          <td>{{ $row['A'] }}</td>
          <td>{{ $row['B'] }}</td>
          ...
       </tr>
  @endforeach
1 голос
/ 03 апреля 2019

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

$arr = [
    ['letter'=>'C'],
    ['letter'=>'A'],
    ['letter'=>'B'],
    ['letter'=>'A'],
    ['letter'=>'D'],
];

// Function to sort by provided column name
function cmp($key){
    // Returns comparision function to be used with usort
    return function($a,$b)use($key){
        return strcmp($a[$key], $b[$key]);
    };
}
usort($arr, cmp('letter'));
print_r($arr);

Надеюсь, это поможет,

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