За последние 24 часа нас посетили 18267 программистов и 1577 роботов. Сейчас ищут 1070 программистов ...

Группировка данных в foreach по определенному полю

Тема в разделе "PHP для новичков", создана пользователем greenzlat, 19 дек 2023.

  1. greenzlat

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

    С нами с:
    27 апр 2008
    Сообщения:
    255
    Симпатии:
    0
    Работаю в CMS opencart. Есть вывод данных. В массиве есть поле article['geo_id'] - ID региона.
    PHP:
    1. <?php foreach ($articles as $article) { ?>
    2.       <div class="swiper-slide" data-geoslide="<?php echo $article['geo_id']; ?>">
    3.           <?php if ($article['thumb']) { ?><div class="popup_img"><img src="<?php echo $article['thumb']; ?>" alt="<?php echo $article['name']; ?>" title="<?php echo $article['name']; ?>" class="img-responsive" /></div>
    4.           <?php } ?>
    5.           <div class="popup_content">
    6.             <div class="popup_wrap">
    7.               <div class="popup_title"><a href="<?php echo $article['href']; ?>"><?php echo $article['name']; ?></a></div>
    8.               <div class="popup_text">
    9.                 <?php echo $article['preview']; ?>
    10.               </div>
    11.             </div>
    12.           </div>
    13.       </div>
    14.       <?php } ?>
    В итоге необходимо этот массив разбить на куски - сгруппировав по geo_id. В итоге должно получиться такое:
    PHP:
    1. <div data-geo="<?php echo $article['geo_id']; ?>" id="geo<?php echo $article['geo_id']; ?>" class="object-popup portfolio_geo">
    2.   <div class="btn_close"></div>
    3.   <div class="swiper-geo<?php echo $article['geo_id']; ?> swiper-container">
    4.     <div class="swiper-wrapper">
    5.       <?php foreach ($articles as $article) { ?>
    6.       <div class="swiper-slide" data-geoslide="<?php echo $article['geo_id']; ?>">
    7.           <?php if ($article['thumb']) { ?><div class="popup_img"><img src="<?php echo $article['thumb']; ?>" alt="<?php echo $article['name']; ?>" title="<?php echo $article['name']; ?>" class="img-responsive" /></div>
    8.           <?php } ?>
    9.           <div class="popup_content">
    10.             <div class="popup_wrap">
    11.               <div class="popup_title"><a href="<?php echo $article['href']; ?>"><?php echo $article['name']; ?></a></div>
    12.               <div class="popup_text">
    13.                 <?php echo $article['preview']; ?>
    14.               </div>
    15.             </div>
    16.           </div>
    17.       </div>
    18.       <?php } ?>
    19.     </div>
    20.   </div>
    21. </div>
    То есть должны сформироваться слайдеры для каждого ГЕО. Подскажите как правильно реализовать?
     
  2. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.854
    Симпатии:
    748
    Адрес:
    Татарстан
    foreach() - не про группировку, а про перебор всех значений

    Не очень понятно что вы хотите... - тот же самый вывод но что каждый слайд был со своим geo_id?
    а какова должна быть логика получения статьи из группы? то есть например для geo_id = 1 будет 5 статей ... вам нужно вывести 1... так? какую? 1-ю, последнюю, случайную?

    В целом решение такое - формируете новый массив по новой логике.. выводите как раньше выводили
     
  3. greenzlat

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

    С нами с:
    27 апр 2008
    Сообщения:
    255
    Симпатии:
    0
    Мне надо весь список статей сгруппировать по одинаковому geo - и сформировать слайдеры по каждому гео.
    Например у меня есть такие данные:
    - статья 1 (geo_id=1)
    - статья 2 (geo_id=2)
    - статья 3 (geo_id=1)
    - статья 4 (geo_id=2)
    - статья 5 (geo_id=1)
    - статья 6 (geo_id=1)
    - статья 7 (geo_id=3)
    - статья 8 (geo_id=1)
    - статья 9 (geo_id=3)
    - статья 10 (geo_id=1)
    - статья 111 (geo_id=2)

    В итоге мне надо вывести их так:
    geo_id=1
    - статья 1
    - статья 3
    - статья 5
    - статья 6
    - статья 8
    - статья 10

    geo_id=2
    - статья 2
    - статья 4

    geo_id=3
    - статья 7
    - статья 9
     
  4. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.854
    Симпатии:
    748
    Адрес:
    Татарстан
    PHP:
    1. <?php
    2. $articles = [
    3.     [
    4.         'geo_id' => 1,
    5.         'name' => 'статья 1'
    6.     ],
    7.     [
    8.         'geo_id' => 2,
    9.         'name' => 'статья 2'
    10.     ],
    11.     [
    12.         'geo_id' => 1,
    13.         'name' => 'статья 3'
    14.     ],
    15.     [
    16.         'geo_id' => 3,
    17.         'name' => 'статья 4'
    18.     ]
    19. ];
    20.  
    21. $geo_articles = [];
    22. foreach ($articles AS $item) {
    23.     $geo_articles[$item['geo_id']][] = $item;  
    24. }
    25.  
    26. echo '<pre>';print_r($geo_articles);
    примерно так... как с искомого массива выводить (с вложенными циклами) наверное разберетесь?
     
    artoodetoo нравится это.
  5. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.105
    Симпатии:
    1.243
    Адрес:
    там-сям
    А ещё в php есть ох*ный набор функций для фильтрации/изменения массивов. Можно творчески его использовать.
    Например, если использовать данные ADSoft:
    PHP:
    1. $geoIds = array_unique(array_column($articles, 'geo_id'));
    2. foreach ($geoIds as $geoId) {
    3.     $filtered = array_filter($articles, fn ($row) => $row['geo_id'] == $geoId);
    4.     echo "geo_id = {$geoId}\n";
    5.     foreach ($filtered as $row) {
    6.         echo ": name = {$row['name']}\n";
    7.     }
    8. }
    выведет
    Код (Text):
    1.  
    2. geo_id = 1
    3. : name = статья 1
    4. : name = статья 3
    5. geo_id = 2
    6. : name = статья 2
    7. geo_id = 3
    8. : name = статья 4
     
  6. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.854
    Симпатии:
    748
    Адрес:
    Татарстан
    подумал про них тоже.. но имхо - по скорости проиграет... по читаемости тоже
     
  7. greenzlat

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

    С нами с:
    27 апр 2008
    Сообщения:
    255
    Симпатии:
    0
    Ошибку выдает : Parse error: syntax error, unexpected '=>' (T_DOUBLE_ARROW), expecting ')' in
    В строке $filtered = array_filter($articles, fn ($row) => $row['geo_id'] == $geoId);
    Версия php 7.3
     
  8. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.105
    Симпатии:
    1.243
    Адрес:
    там-сям
    @greenzlat "стрелочные" функции как развитие анонимных функций появились в PHP 7.4
    я бы не советовал сейчас пользоваться 7.3, она устарела. никто не будет проверять свои примеры на совместимость с тем, что устарело годы назад. просто прими это.
    https://www.php.net/supported-versions.php
    --- Добавлено ---
    переделать на не-стрелочный вариант можешь сам.
     
  9. greenzlat

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

    С нами с:
    27 апр 2008
    Сообщения:
    255
    Симпатии:
    0
    Да на локалке 7.3 включена была. Переключил - все норм стало! Спасибо, вроде разобрался.