За последние 24 часа нас посетили 17684 программиста и 1362 робота. Сейчас ищут 1172 программиста ...

Сортировка и группировка массива

Тема в разделе "PHP для новичков", создана пользователем amf1k, 24 фев 2025.

  1. amf1k

    amf1k Активный пользователь

    С нами с:
    20 авг 2014
    Сообщения:
    86
    Симпатии:
    0
    Помогите отсортировать массив!
    Я хочу вывести фильмы с определенным годом (пример ссылки index.php?type=movies&year=2005), мне нужно будет выводит и группировку по 1-му символу, и по определенному году(здесь 2 цикла)!
    Вот мой массив:
    PHP:
    1. (
    2.     [А] => Array
    3.         (
    4.             [0] => Array
    5.                 (
    6.                     [title] => Американский пирог
    7.                     [year] => 2005
    8.                 )
    9.  
    10.             [1] => Array
    11.                 (
    12.                     [title] => Астрал
    13.                     [year] => 2005
    14.                 )
    15.  
    16.             [2] => Array
    17.                 (
    18.                     [title] => Автор книги по ФИЛЬМАМ
    19.                     [year] => 2010
    20.                 )
    21.  
    22.         )
    23.  
    24.     [Б] => Array
    25.         (
    26.             [0] => Array
    27.                 (
    28.                     [title] => Багратион
    29.                     [year] => 2005
    30.                 )
    31.  
    32.         )
    33.  
    34.     [О] => Array
    35.         (
    36.             [0] => Array
    37.                 (
    38.                     [title] => Один дома
    39.                     [year] => 2001
    40.                 )
    41.  
    42.             [1] => Array
    43.                 (
    44.                     [title] => Один дома 2
    45.                     [year] => 2014
    46.                 )
    47.  
    48.             [2] => Array
    49.                 (
    50.                     [title] => Овен
    51.                     [year] => 2014
    52.                 )
    53.  
    54.         )
    55.  
    56.     [0-9] => Array
    57.         (
    58.             [0] => Array
    59.                 (
    60.                     [title] => 7 Джеймс Бонд
    61.                     [year] => 2007
    62.                 )
    63.  
    64.             [1] => Array
    65.                 (
    66.                     [title] => 5 элемент
    67.                     [year] => 2011
    68.                 )
    69.  
    70.         )
    71.  
    72.     [A-Z] => Array
    73.         (
    74.             [0] => Array
    75.                 (
    76.                     [title] => Good Movie
    77.                     [year] => 2003
    78.                 )
    79.  
    80.             [1] => Array
    81.                 (
    82.                     [title] => Doom
    83.                     [year] => 2004
    84.                 )
    85.  
    86.         )
    87.  
    88. )
    Нужно вывести с все фильмы 2005 года в таком формате:
    А
    Американский пирог (2005)
    Астрал (2005)
    Б
    Багратион (2005)

    А я на выходе получаю правильное значение фильмов, но только лишние категории, как отредактировать цикл?
    А
    Американский пирог (2005)
    Астрал (2005)
    Б
    Багратион (2005)
    О
    0-9
    A-Z

    Вот мой код: у меня неправильная логика в цикле!
    PHP:
    1. foreach($movies as $groups => $arr){
    2.                     echo '<a href="index.php?type=movies&groups='.$groups.'">'.$groups.'</a><br/>';
    3.                     foreach($arr as $value){
    4.                         //Если $_GET['year'] равна $value['year']
    5.                         if($_GET['year'] == $value['year']){
    6.                             echo $value['title']. '<a href="index.php?type=movies&year='.$value['year'].'">('.$value['year'].')</a><br/>';
    7.                         }
    8.                     }
    9.                 }
     
  2. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.500
    Симпатии:
    282
  3. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    485
    Симпатии:
    94
    Адрес:
    Бавария, Германия

    Добрый день!

    Вы не верно сформулировали задачу.
    Вам не нужно сортировать массив. Он уже как-то, пусть и страно, отсортирован.
    Вы написали:
    т.е. Вам нужно убрать пустые котегории при выводе списка.
    Попробуйте так:
    PHP:
    1. $noEmptyMoviesListe = [];
    2. foreach($movies as $groups => $arr){
    3.     foreach($arr as $value){
    4.         //Если $_GET['year'] равна $value['year']
    5.         if($_GET['year'] == $value['year'])
    6.            $noEmptyMoviesListe[$groups][]=$value;
    7.     }
    8. }
    9.  
    10. if($noEmptyMoviesListe){
    11.     foreach($noEmptyMoviesListe as $groups => $arr){
    12.         echo "<a href=\"index.php?type=movies&groups=$groups\">$groups</a><br/>";
    13.         foreach($arr as $value)
    14.             echo "{$value['title']} <a href=\"index.php?type=movies&year={$value['year']}\">({$value['year']})</a><br/>";
    15.     }
    16. }
    17. else
    18.     echo "Не найдено ни одного фильма {$_GET['year']} года";
    Удачи!
     
    #3 Vladimir Kheifets, 3 мар 2025
    Последнее редактирование: 3 мар 2025
  4. amf1k

    amf1k Активный пользователь

    С нами с:
    20 авг 2014
    Сообщения:
    86
    Симпатии:
    0
    Сделал что то подобное, только по метках!
    Вот мой код:
    PHP:
    1.                 foreach($movies as $groups => $arr){
    2.                     //Убирает метку, что бы сработал вывод следующей строки группы
    3.                     unset($nr);
    4.                     foreach($arr as $value){
    5.                         //Если $_GET['year'] равна $value['year']
    6.                         if($_GET['year'] == $value['year']){
    7.                             //Вывод работает только если нету метки
    8.                             if(!isset($nr)){
    9.                                 //Это строка названия группы
    10.                                 echo '<a href="index.php?type=movies&groups='.$groups.'">'.$groups.'</a><br/>';
    11.                                 //Метка что бы строка выводилась один раз
    12.                                 $nr = true;
    13.                             }
    14.                             //Это строка названия и год выхода фильма
    15.                             echo $value['title']. '<a href="index.php?type=movies&year='.$value['year'].'">('.$value['year'].')</a><br/>';
    16.                         }
    17.                     }
    18.                 }
     
  5. amf1k

    amf1k Активный пользователь

    С нами с:
    20 авг 2014
    Сообщения:
    86
    Симпатии:
    0
    Теперь возник 2-й вопрос (по поиску фильма), изначально была идея искать один фильм в массиве (по названию фильма), но возник вопрос (а если будет 2 фильма с одинаковыми названиями - но разными годами выхода фильмов, или 3 фильма), то мне нужно выводить результат!
    Мой код (с break) работает, если нужно выводить только 1 фильм, если 2 и больше, код не работает (потому что функция break)!
    PHP:
    1.         foreach($movies as $arr){
    2.                     foreach($arr as $value){
    3.                         if($_POST['result'] == trim($value['title'])){
    4.                             $result = $value['title'].'<a href="index.php?type=movies&year='.$value['year'].'">('.$value['year'].')</a>';
    5.                             break(2);
    6.                         }
    7.                         else{
    8.                             $result = 'Нет совпадений!';
    9.                         }
    10.                     }
    11.                 }
    12.                 echo $result;
    Что бы этот поиск реализовать, мне нужно создать пустой массив (перед 1-м foreach), и уже во 2-м цикле сравнивать POST и $value, и заносить информацию в пустой массив, это все желательно реализовать (отдельная функция), и уже потом (новый массив) выводить в цикле (БОЛЬШЕ У МЕНЯ НЕТ ИДЕЙ - КАК ПРАВИЛЬНО ДЕЛАТЬ)! Но я не могу это реализовать в коде, если я убираю функцию break, то мне условие
    PHP:
    1. if($_POST['result'] == trim($value['title']))
    всегда выдает
    PHP:
    1. $result = 'Нет совпадений!';
     
  6. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    485
    Симпатии:
    94
    Адрес:
    Бавария, Германия
    Добрый день!
    про Ваш код:
    А если по условию поиску ничего не выбрано, а Вы уже отправили HTML?
    Если $movies пустой, то будет фатальная ошибка в foreach.
    Добавил в Ваш массив Багратион, 2010
    PHP:
    1. $movies = [
    2.     "А" => [
    3.  
    4.             0 => [
    5.  
    6.                     "title" => "Американский пирог",
    7.                     "year" => 2005
    8.                 ],
    9.             1 => [
    10.  
    11.                     "title" => "Астрал",
    12.                     "year" => 2005
    13.                 ],
    14.             2 => [
    15.  
    16.                     "title" => "Автор книги по ФИЛЬМАМ",
    17.                     "year" => 2010
    18.                 ]
    19.         ],
    20.     "Б" => [
    21.  
    22.             "0" => [
    23.  
    24.                     "title" => "Багратион",
    25.                     "year" => 2005
    26.                 ],
    27.             "1" => [
    28.  
    29.                     "title" => "Багратион",
    30.                     "year" => 2010
    31.                 ]
    32.  
    33.         ],
    34.     "О" => [
    35.  
    36.             0 => [
    37.  
    38.                     "title" => "Один дома",
    39.                     "year" => 2001
    40.                 ],
    41.             1 => [
    42.  
    43.                     "title" => "Один дома 2",
    44.                     "year" => 2014
    45.                 ],
    46.             2 => [
    47.  
    48.                     "title" => "Овен",
    49.                     "year" => 2014
    50.  
    51.                 ]
    52.         ],
    53.     "0-9" => [
    54.  
    55.             0 =>[
    56.  
    57.                     "title" => "7 Джеймс Бонд",
    58.                     "year" => 2007
    59.                 ],
    60.             1 => [
    61.  
    62.                     "title" => "5 элемент",
    63.                     "year" => 2011
    64.                  ]
    65.  
    66.         ],
    67.     "A-Z" => [
    68.  
    69.             0 => [
    70.  
    71.                     "title" => "Good Movie",
    72.                     "year" => 2003
    73.                 ],
    74.             1 => [
    75.  
    76.                     "title" => "Doom",
    77.                     "year" => 2004
    78.                 ]
    79.         ]
    80.  
    81. ];
    82.  
    83.  
    84. function getNoEmptyMoviesListe( $filterKey, $filterValue, $movies){
    85.     $noEmptyMoviesListe = [];  
    86.  foreach((array) $movies as $groups => $arr){
    87.         foreach($arr as $value){
    88.             if($value[$filterKey] == $filterValue)
    89.                     $noEmptyMoviesListe[$groups][]=$value;
    90.         }
    91.     }
    92.  
    93.     return  $noEmptyMoviesListe;
    94. }
    95.  
    96. $filterKey="year";
    97. $filterValue = 2005;
    98.  
    99. $noEmptyMoviesListe = getNoEmptyMoviesListe( $filterKey, $filterValue, $movies);
    100.  
    101.  
    102. if($noEmptyMoviesListe){
    103.     foreach($noEmptyMoviesListe as $groups => $arr){
    104.         echo "<a href=\"index.php?type=movies&groups=$groups\">$groups</a><br/>";
    105.         foreach($arr as $value)
    106.             echo "{$value['title']} <a href=\"index.php?type=movies&year={$value['year']}\">({$value['year']})</a><br/>";
    107.     }
    108. }
    109. else
    110.     echo "Поиск: $filterKey $filterValue. Не найдено ни одного фильма";
    111.  
    112. /*
    113. А
    114. Американский пирог (2005)
    115. Астрал (2005)
    116. Б
    117. Багратион (2005)
    118. */
    119.  
    120. $filterKey = "title";
    121. $filterValue = "Багратион";
    122.  
    123. /*
    124. Б
    125. Багратион (2005)
    126. Багратион (2010)
    127. */
    Удачи!
     
    #6 Vladimir Kheifets, 6 мар 2025
    Последнее редактирование: 6 мар 2025
  7. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    485
    Симпатии:
    94
    Адрес:
    Бавария, Германия
    Дополнение
    PHP:
    1. function getNoEmptyMoviesListe( $filterKey, $filterValue, $movies){
    2.     $noEmptyMoviesListe = [];
    3.     foreach((array) $movies as $groups => $arr){
    4.         foreach($arr as $value){
    5.             if($value[$filterKey] == $filterValue)
    6.                     $noEmptyMoviesListe[$groups][]=$value;
    7.         }
    8.     }
    9.     return  $noEmptyMoviesListe;
    10. }
    11.  
    12.  
    13. function viewLinks($inMovies){
    14.     if($inMovies){
    15.         foreach($inMovies as $groups => $arr){
    16.             echo "<a href=\"index.php?type=movies&groups=$groups\">$groups</a><br/>";
    17.             foreach($arr as $value)
    18.                 echo "{$value['title']} <a href=\"index.php?type=movies&year={$value['year']}\">({$value['year']})</a><br/>";
    19.         }
    20.     }
    21.     else
    22.         echo "Поиск: $filterKey $filterValue. Не найдено ни одного фильма";
    23. }
    24.  
    25. $filterKey = "year";
    26. $filterValue = 2005;
    27.  
    28. if(preg_match("/(title|year)/",$filterKey) && $filterValue)
    29.     viewLinks(getNoEmptyMoviesListe( $filterKey, $filterValue, $movies));
    30. else
    31.     viewLinks($movies);
     
  8. amf1k

    amf1k Активный пользователь

    С нами с:
    20 авг 2014
    Сообщения:
    86
    Симпатии:
    0
    Спасибо!
    Немного переписал ваш код, вот что получилось(создал 2 функции), добавил 2-й массив с мультфильмами:
    PHP:
    1. //Функция - узнаем цифру и её окончание (например) Найден(ы) 1 фильм(ы)
    2. function iResult($i){
    3.     switch($i){
    4.         case 1:
    5.             $result = 'Найден '.$i.' кинокартина';
    6.         break;
    7.         case 2:
    8.             $result = 'Найдены '.$i.' кинокартины';
    9.         break;
    10.         case 3:
    11.             $result = 'Найдены '.$i.' кинокартины';
    12.         break;
    13.         case 4:
    14.             $result = 'Найдены '.$i.' кинокартины';
    15.         break;
    16.         case 5:
    17.             $result = 'Найдены '.$i.' кинокартин';
    18.         break;
    19.     }
    20.     return $result;
    21. }
    22. //Функция поиска на сайте
    23. function searchPost($post,$movies,$animations){
    24.     //Если ввели название фильма или мультфильма
    25.     if(!empty($post)){
    26.         //Счетчик (количество найденных фильмов и мультфильмов)
    27.         $i = 0;
    28.         $result = null;
    29.         //Приводит строку POST к нижнему регистру
    30.         $post_title = mb_strtolower($post,'utf-8');
    31.         //Поиск фильма
    32.         foreach($movies as $array){
    33.             foreach($array as $value){
    34.                 //Приводит строку $value['title'] к нижнему регистру, удаляем пробелы
    35.                 $value_title = mb_strtolower(trim($value['title']),'utf-8');
    36.                 //Если название введенного фильма совпадаем с фильмов в массиве
    37.                 if($post_title == $value_title){
    38.                     //Добавляем счетчик +1
    39.                     $i ++;
    40.                     //Записываем результат
    41.                     $result = $result.'<span>'.$value['title'].'<a href="index.php?type=movies&year='.$value['year'].'">('.$value['year'].')</a></span><br/>';
    42.                 }
    43.             }              
    44.         }
    45.         //Поиск мультфильма
    46.         foreach($animations as $array){
    47.             foreach($array as $value){
    48.                 //Приводит строку $value['title'] к нижнему регистру, удаляем пробелы
    49.                 $value_title = mb_strtolower(trim($value['title']),'utf-8');
    50.                 //Если название введенного фильма совпадаем с фильмов в массиве
    51.                 if($post_title == $value_title){
    52.                     //Добавляем счетчик +1
    53.                     $i ++;
    54.                     //Записываем результат
    55.                     $result = $result.'<span>'.$value['title'].'<a href="index.php?type=animations&year='.$value['year'].'">('.$value['year'].')</a></span><br/>';
    56.                 }
    57.             }              
    58.         }
    59.         //Если фильмы или мультфильмы были найдены
    60.         if(!empty($result)){
    61.             //Выводим результат поиска
    62.             echo '<div class="search_result_title"><h5>'.iResult($i).':</h5>'.$result.'</div>';
    63.         }
    64.         //Вдруг ничего не найдено
    65.         else{
    66.             //Возвращаем false
    67.             return 'false';
    68.         }
    69.     }
    70.     //Если не ввели название фильма или мультфильма
    71.     else{
    72.         //Возвращаем null
    73.         return 'null';
    74.     }
    75. }
    Вывод на странице:
    PHP:
    1. //Если не ввели название фильма или мультфильма
    2.             if($search == 'null'){
    3.                 //Выводим сообщение
    4.                 echo 'Введи название фильма или мультфильма!';
    5.             }
    6.             else{
    7.                 //Вдруг ничего не найдено
    8.                 if($search == 'false'){
    9.                     //Выводим сообщение что нечего не найдено
    10.                     echo 'Нет совпадений!';
    11.                 }
    12.                 else{
    13.                     echo $search;
    14.                 }
    15.             }
    Теперь не пойму, почему во 2-й функции return 'false'; и return 'null'; возвращает только в форме строки, если возвратить return false и return null, то у меня на выводе неправильно срабатывает условие if($search == null), только в формате строки срабатывает корректно if($search == 'null'), в чем может быть моя ошибка ?
     
  9. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    485
    Симпатии:
    94
    Адрес:
    Бавария, Германия
    Добрый день!
    В первой функции switch можно убрать
    PHP:
    1. function iResult($i){
    2.     switch($i){
    3.         case 1:
    4.     $result = 'Найден '.$i.' кинокартина';
    5.             break;
    6.             case 2:
    7.     $result = 'Найдены '.$i.' кинокартины';
    8.             break;
    9.            ...
    10.     case 5:
    11.                 $result = 'Найдены '.$i.' кинокартин';
    12.             break;
    13.  
    14.     }
    15.     return $result;
    16. }
    Тот же ресультат выдаст эта функция
    PHP:
    1. function iResult($i){
    2.     if($i==1)
    3.         $result =  "Найдена 1  кинокартина";
    4.     else if($i>1 AND $i<5)
    5.         $result = "Найдены $i кинокартины";
    6.     else
    7.           $result = "Найдено $i  кинокартин"
    8.     return $result;
    9. }
    По второй функции
    function searchPost($post,$movies,$animations){

    1. Повторяется два блока

    foreach($movies as $array){
    foreach($animations as $array){

    Лучше изменить параметры функции так
    function searchPost($post, $filmAnimation){
    и оставить один блок foreach

    foreach($filmAnimation as $array){

    и делать два вызова функции

    searchPost($post,$movies)
    searchPost($post,$animations)


    2. тут ошибка
    PHP:
    1. if($post_title == $value_title){
    2.    //Добавляем счетчик +1
    3.     $i ++;
    4.     //Записываем результат
    5.     $result = $result.'<span>'.$value['title'].'<a href="index.php?type=movies&year='.$value['year'].'">('.$value['year'].')</a></span><br/>';
    6. }
    Счетчик наращивается, а $result нет.
    Функция будет возвращать толко одну остроку.

    3. Функция должна возвращать строку, а не null или false
    Вывод результата
    PHP:
    1. //Если не ввели название фильма или мультфильма
    2. if(empty($post)){
    3.     //Выводим сообщение
    4.     echo 'Введи название фильма или мультфильма!';
    5. }
    6. else if($search;)
    7.     echo $search;
    8. else{
    9.     //Выводим сообщение что нечего не найдено
    10.     echo 'Нет совпадений!';
    11. }
    Удачи!
     
    #9 Vladimir Kheifets, 10 мар 2025
    Последнее редактирование: 10 мар 2025