За последние 24 часа нас посетили 20862 программиста и 1010 роботов. Сейчас ищут 367 программистов ...

Удаление пустых элементов массива

Тема в разделе "PHP для новичков", создана пользователем Yankovitz, 14 мар 2019.

  1. Yankovitz

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

    С нами с:
    21 ноя 2014
    Сообщения:
    194
    Симпатии:
    6
    Добрый день. Есть один большой массив массивов (количество последних не ограничено):
    Код (Text):
    1.     [0] => Array
    2.         (
    3.             [0] => Наименование
    4.             [1] => Размер, мм
    5.             [2] => Ширина, мм
    6.             [3] => Марка
    7.             [4] => Диаметр, мм
    8.             [5] => Длина, мм
    9.         )
    10.     [1] => Array
    11.         (
    12.             [0] => Профнастил окрашен. 9002 Н114 оцинкованный
    13.             [1] =>
    14.             [2] => 0.9
    15.             [3] => 2
    16.             [4] =>
    17.             [5] =>
    18.         )
    19.     [2] => Array
    20.         (
    21.             [0] => Профнастил С21 оцинкованный
    22.             [1] => 1
    23.             [2] => 0.5
    24.             [3] =>
    25.             [4] =>
    26.             [5] =>
    27.         )
    Нужно удалить элементы, которые пустые во всех массивах с исключением из расчётов первого. Должно получиться вот так:
    Код (Text):
    1.   [0] => Array
    2.         (
    3.             [0] => Наименование
    4.             [1] => Размер, мм
    5.             [2] => Ширина, мм
    6.             [3] => Марка
    7.         )
    8.     [1] => Array
    9.         (
    10.             [0] => Профнастил окрашен. 9002 Н114 оцинкованный
    11.             [1] =>
    12.             [2] => 0.9
    13.             [3] => 2
    14.         )
    15.     [2] => Array
    16.         (
    17.             [0] => Профнастил С21 оцинкованный
    18.             [1] => 1
    19.             [2] => 0.5
    20.             [3] =>
    21.         )
     
  2. Valick

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

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @Yankovitz, собственных мыслей по этому поводу никаких?
     
  3. Yankovitz

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

    С нами с:
    21 ноя 2014
    Сообщения:
    194
    Симпатии:
    6
    Есть, но получается просто жесть. Стыдно даже показывать. Несколько раз перебираю foreach.
     
  4. Babka_Gadalka

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

    С нами с:
    16 фев 2019
    Сообщения:
    162
    Симпатии:
    23
    Адрес:
    Москва, Пушкина, Избушкина, 2й этаж душечка.
    array_map с array_filter
    --- Добавлено ---
    можно и с 2 foreach где проверяем на пустоту и просто чистим элементы дочернего массива
     
  5. Yankovitz

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

    С нами с:
    21 ноя 2014
    Сообщения:
    194
    Симпатии:
    6
    Да, спасибо. В общем так и сделал. Тему можно закрыть.
     
  6. Valick

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

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @Yankovitz, прежде чем закрывать тему, не плохо было бы показать результат.
    --- Добавлено ---
    @artoodetoo, удалить пустые которые пустые во всех массивах исключая первый.
     
  7. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Включая первый, если ни в одном соседнем нет такого,
    проблема тут только что тс не сделал var_export ;)
     
  8. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    Я понял :)
    если $array исходный массив, то вот так:
    PHP:
    1. $body = $array;
    2. // cut first row, get keys (non-numeric keys are accepted)
    3. $keys = array_keys(array_shift($body));
    4. $lengths = [];
    5.  
    6. // find total length of each column element
    7. foreach ($body as $r) {
    8.   foreach ($keys as $k) {
    9.     $lengths[$k] += strlen($r[$k]);
    10.   }
    11. }
    12.  
    13. // remove empty columns
    14. foreach ($array as &$r) {
    15.   foreach ($keys as $k) {
    16.     if ($lengths[$k] == 0) {
    17.       unset($r[$k]);
    18.     }
    19.   }
    20. }
    21. unset($r); // just in case :)
    ключи на втором уровне вложенности не обязательно должны быть числами. если это имена полей, например, тоже прокатит.
    не учитывается выроженный случай, когда в массиве только строка с заголовками. не знаю что нужно при таком раскладе, то ли удалять всё, то ли не делать ничего )))
     
  9. Valick

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

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @keren, цитирую
     
  10. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    @Valick
    Есть мысли по коду? ;)
     
  11. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    PHP Notice: Undefined offset: 0 1 2 3 4 5
    В $body 3 элемента сравнивается с 5 ключами подмассива,
    оно работает но это не так как нужно .....
     
  12. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    Я исходил из того, что ключи одни и те же в строке заголовка и в рядах данных. Помоему вполне естественное предположение. Но похоже вы создали иной входной массив. То ли с разными ключами, то ли с рядами разной длинны.
    --- Добавлено ---
    Я также написал, что с пустым массивом данных это не работает.
    --- Добавлено ---
    Я не понимаю что вы имеете в виду :) ну допустим 3 ряда * 5 элементов и что? :)
    --- Добавлено ---
    Короче, @keren, есть ощущение, что вы работаете с говёными исходными данными. Не могли бы вы скопировать из сюда.
     
  13. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Это массив:
    PHP:
    1. $array = array (
    2.   0 =>
    3.   array (
    4.     0 => 'Наименование',
    5.     1 => 'Размер, мм',
    6.     2 => 'Ширина, мм',
    7.     3 => 'Марка',
    8.     4 => 'Диаметр, мм',
    9.     5 => 'Длина, мм',
    10.   ),
    11.   1 =>
    12.   array (
    13.     0 => 'Профнастил окрашен. 9002 Н114 оцинкованный',
    14.     1 => '',
    15.     2 => 0.9,
    16.     3 => 2,
    17.     4 => '',
    18.     5 => '',
    19.   ),
    20.   2 =>
    21.   array (
    22.     0 => 'Профнастил С21 оцинкованный',
    23.     1 => 1,
    24.     2 => 0.5,
    25.     3 => '',
    26.     4 => '',
    27.     5 => '',
    28.   )
    29. );
    Переписал так:
    PHP:
    1. foreach ($body as $r) {
    2.   foreach ($r as $k => $v) {
    3.     $lengths[$k] += strlen($v);
    4.   }
    5. }
    Выводит тоже самое с нотисами ...
     
  14. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Там всего лишь добавить:
    PHP:
    1. if(empty($lengths[$k])) $lengths[$k] = 0;
     
    artoodetoo нравится это.
  15. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    OK. согласен ) или вместо $lengths = [] поставить
    $lentghs = array_fill_keys($keys, 0)