За последние 24 часа нас посетили 18246 программистов и 833 робота. Сейчас ищут 435 программистов ...

Как из массива удалить четные элементы?

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

  1. Bonso

    Bonso Новичок

    С нами с:
    18 янв 2024
    Сообщения:
    3
    Симпатии:
    0
    PHP:
    1. <?php
    2.  
    3. //Дан массив:
    4.  
    5. $array = ['q','w','e','r','t','y'];
    6.  
    7. //Из него нужно удалить все четные элементы
    8.  
    9. ?>
     
  2. Slava Rozhnev

    Slava Rozhnev Новичок

    С нами с:
    6 сен 2021
    Сообщения:
    87
    Симпатии:
    26
    Адрес:
    https://phpize.online
    Это банальная задача и можно придумать множество решений. Например так: foreach
     
  3. Survivor

    Survivor Новичок

    С нами с:
    8 фев 2023
    Сообщения:
    54
    Симпатии:
    6
    Не в обиду :)
    Можно просто обойтись
    PHP:
    1. unset($array[$key]);
    и не пересоздавать массив

    А так прав, вариантов 6 как минимум точно есть))
     
    Slava Rozhnev нравится это.
  4. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    196
    Симпатии:
    29
    Адрес:
    Бавария, Германия
    PHP:
    1. <?php
    2. //Дан массив:
    3. $array = ['q','w','e','r','t','y'];
    4. echo "<pre>";
    5. print_r($array);
    6. /*
    7. Array
    8. (
    9.   [0] => q
    10.   [1] => w
    11.   [2] => e
    12.   [3] => r
    13.   [4] => t
    14.   [5] => y
    15. )
    16. */
    17. foreach(array_filter(array_keys($array), function($key) {return !($key & 1);}) as $key)
    18.  unset($array[$key]);
    19. print_r($array);
    20. /*
    21. Array
    22. (
    23.   [1] => w
    24.   [3] => r
    25.   [5] => y
    26. )
    27. */
    28. ?>
     
  5. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    196
    Симпатии:
    29
    Адрес:
    Бавария, Германия
    Решение №2
    PHP:
    1. array_walk($array, function ($value, $key) {
    2.   global $array;
    3.   if(!($key & 1)) unset($array[$key]);
    4. });
    Решение №3
    PHP:
    1. for ($i=0; $i <= count($array); $i=$i+2) {
    2.   unset($array[$i]);
    3. }
    Решение №4
    PHP:
    1. $i=0;
    2. while ($i<=count($array)) {
    3.   unset($array[$i]);
    4.   $i+=2;
    5. }
     
  6. amberson

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

    С нами с:
    23 июл 2020
    Сообщения:
    61
    Симпатии:
    12
    Оставлю свой вариант
    PHP:
    1. $array = ['q','w','e','r','t','y'];
    2.  
    3. $result = array_filter($array, fn ($i) => ! ($i % 2), ARRAY_FILTER_USE_KEY);
    4.  
    5. print_r($result);
     
  7. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    196
    Симпатии:
    29
    Адрес:
    Бавария, Германия
    Вы задали вопрос:
    PHP:
    1. //Дан массив:
    2. $array = ['q','w','e','r','t','y'];
    3. //Из него нужно удалить все чётные элементы
    Ваш вариант не удаляет все чётные элементы из массива $array,
    а копирует нечётные элементы из этого массива в массив $result.
     
  8. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    196
    Симпатии:
    29
    Адрес:
    Бавария, Германия
    Дополнение. Простой тест показывает, что наилучшее решение.
    PHP:
    1. for ($i=0; $i <= count($array); $i=$i+2) {
    2. unset($array[$i]);
    3. }
    Execution time: 0.227 ms
    Ваш вариант
    PHP:
    1. $result = array_filter($array, fn ($i) => ! ($i % 2), ARRAY_FILTER_USE_KEY);
    Execution Time: 1.5817 ms
    Тест
    PHP:
    1. <?php
    2. //Дан массив:
    3. //$array = ['q','w','e','r','t','y'];
    4. ###############################################
    5. function getExecutionTime($time_start){
    6.     return (hrtime(true) - $time_start)/1e+6;
    7. }
    8. ###############################################
    9. $array = str_split(file_get_contents("https://php.ru/"));
    10. echo "Count array: ", count($array),"<hr>";
    11. echo 'Code 1.<br>
    12. $result = array_filter($array, fn ($i) => ! ($i % 2), ARRAY_FILTER_USE_KEY);<br>';
    13. $time_start = hrtime(true);
    14. $result = array_filter($array, fn ($i) => ! ($i % 2), ARRAY_FILTER_USE_KEY);
    15. $executionTime1 = getExecutionTime($time_start);
    16. echo "<b>Execution Time1:</b> $executionTime1 ms<hr>";
    17. ######################################################################
    18. echo 'Code 2.<br>
    19. $i=0;<br>
    20. while ($i<=count($array)) {<br>
    21.    unset($array[$i]);<br>
    22.    $i+=2;<br>
    23. }<br>';
    24.  
    25. $time_start = hrtime(true);
    26. $i=0;
    27. while ($i<=count($array)) {
    28.     unset($array[$i]);
    29.     $i+=2;
    30. }
    31. $executionTime2 = getExecutionTime($time_start);
    32. echo "<b>Execution time2:</b> $executionTime2 ms<hr>";
    33. ######################################################################
    34. echo 'Code 3.<br>for ($i=0; $i <= count($array); $i=$i+2) {<br>
    35.    unset($array[$i]);<br>
    36. }<br>';
    37. $time_start = hrtime(true);
    38. for ($i=0; $i <= count($array); $i=$i+2) {
    39.     unset($array[$i]);
    40. }
    41. $executionTime3 = getExecutionTime($time_start);
    42. echo "<b>Execution time3:</b> $executionTime3 ms<hr>";
    43. ######################################################################
    44. $diff = $executionTime1 - $executionTime2;
    45. echo "<b>Сode 2 is faster than Сode 1 by :</b> $diff ms<br>";
    46. $diff = $executionTime1 - $executionTime3;
    47. echo "<b>Сode 3 is faster than Сode 1 by :</b> $diff ms<br>";
    48. /*
    49. Count array: 23154
    50.  
    51. Code 1.
    52. $result = array_filter($array, fn ($i) => ! ($i % 2), ARRAY_FILTER_USE_KEY);
    53. Execution Time1: 1.5817 ms
    54.  
    55. Code 2.
    56. $i=0;
    57. while ($i<=count($array)) {
    58. unset($array[$i]);
    59. $i+=2;
    60. }
    61. Execution time2: 0.2732 ms
    62.  
    63. Code 3.
    64. for ($i=0; $i <= count($array); $i=$i+2) {
    65. unset($array[$i]);
    66. }
    67. Execution time3: 0.227 ms
    68.  
    69. Сode 2 is faster than Сode 1 by : 1.3085 ms
    70. Сode 3 is faster than Сode 1 by : 1.3547 ms
    71. ?>
    Удачи!
     
    #8 Vladimir Kheifets, 12 фев 2024
    Последнее редактирование: 12 фев 2024
  9. amberson

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

    С нами с:
    23 июл 2020
    Сообщения:
    61
    Симпатии:
    12
    Vladimir Kheifets, пара моментов.

    Первое, твой вариант не удаляет четные элементы из массива. И вообще данный подход не работает на массивах имеющих свыше шести элементов. Попробуй разобраться почему так происходит.

    Второе, при чтении подобного решения в коде, возникнет когнитивная нагрузка на читающего во время которой он будет пытаться понять что тут происходит, зачем итерируемый массив изменяет сам себя удаляя свои же элементы во время этих итераций. Эта нагрузка будет стоить дороже чем та экономия на спичках которую ты приводишь, если эта экономия там еще и будет.
     
  10. Survivor

    Survivor Новичок

    С нами с:
    8 фев 2023
    Сообщения:
    54
    Симпатии:
    6
    Ощущение, что занимаюсь какой-то херней))) ну да ладно!

    PHP:
    1. <?php
    2. declare(strict_types = 1); //- Строгая типизация в PHP
    3. error_reporting(-1); //- Показываем все ошибки
    4.  
    5.  
    6. function getExecutionTime($time_start)
    7. {
    8.     return (hrtime(true) - $time_start)/1e+6;
    9. }
    10.  
    11.  
    12. $array = str_split(file_get_contents("https://php.ru/"));
    13.  
    14.  
    15. $time_start = hrtime(true);
    16.  
    17.  
    18. //- 1 вариант в среднем 3,5
    19. /*
    20. foreach ($array as $key => $value) {
    21.     if ($key % 2 == 0) { // Удаляем элементы с четными индексами
    22.         unset($array[$key]);
    23.     }
    24. }
    25. */
    26.  
    27.  
    28.  
    29.  
    30.  
    31. /*
    32. //- 2 вариант в среднем 4.7
    33. $result = array_filter($array, function($key) {
    34.     return $key % 2 !== 0; // Оставляем элементы с нечетными индексами
    35. }, ARRAY_FILTER_USE_KEY);
    36.  
    37. */
    38.  
    39.  
    40.  
    41.  
    42.  
    43.  
    44. /*
    45. //- 3 вариант в среднем 2.5
    46. $newArray = [];
    47. foreach ($array as $key => $value) {
    48.     if ($key % 2 !== 0) { // Добавляем элементы с нечетными индексами
    49.         $newArray[] = $value;
    50.     }
    51. }
    52. */
    53.  
    54.  
    55.  
    56.  
    57.  
    58. /*
    59. //- 4 вариант в среднем 5.9
    60. $keysToRemove = array_filter(array_keys($array), function($key) {
    61.     return $key % 2 == 0;
    62. });
    63. foreach ($keysToRemove as $key) {
    64.     unset($array[$key]);
    65. }
    66. */
    67.  
    68.  
    69.  
    70. /*
    71.  
    72. //- 5 вариант в среднем 7.4
    73. array_walk($array, function($value, $key) use (&$array) {
    74.     if ($key % 2 == 0) {
    75.         unset($array[$key]);
    76.     }
    77. });
    78.  
    79. */
    80.  
    81.  
    82. /*
    83. //- 6 вариант в среднем 2.5
    84. // Итерируем в обратном порядке, чтобы не пропустить элементы после удаления
    85. for ($i = count($array) - 1; $i >= 0; $i--) {
    86.     if ($i % 2 == 0) { // Проверяем, является ли индекс четным
    87.         unset($array[$i]);
    88.     }
    89. }
    90. // Для корректного вывода массива с последовательными индексами
    91. $array = array_values($array);
    92. */
    93.  
    94.  
    95. //print_r($result);
    96.  
    97.  
    98.  
    99.  
    100.  
    101.  
    102. $executionTime1 = getExecutionTime($time_start);
    103. echo "<b>Execution Time1:</b> $executionTime1 ms<hr>";
    104.  
    105. ?>

    Позаимствовал чуть кода у Vladimir Kheifets.
    Закомментировал каждый из тестов + описание.

    Насколько я понимаю, то время выполнения может, и зависит от многих факторов, как параметры сервера, так и версия php + нагрузка.
    При работе с маленькими массивами, я думаю, что можно использовать любой из вариантов. Главное ведь что? - достичь цели))

    p.s. параметры где тестировалось:

    Debian 10 (Buster), nginx/1.14.2, PHP 8.3.0

    Intel Xeon D1540 - 8c/16t - 2 GHz/2.6 GHz
    32 GB ECC 2133 MHz
    2×450 GB SSD NVMe
    250 Mbps outgoing
     
    #10 Survivor, 12 фев 2024
    Последнее редактирование: 12 фев 2024
  11. Drunkenmunky

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

    С нами с:
    12 авг 2020
    Сообщения:
    1.475
    Симпатии:
    281
    А так?
    PHP:
    1. //$array = .....
    2. $new_array = array_column(array_chunk($array, 2), 0);
    3. $print_r($new_array);
     
    amberson нравится это.
  12. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    829
    Симпатии:
    129
    Не понял, чем array_filter() не устроил:
    PHP:
    1. <?php
    2.  
    3. echo "<pre>";
    4.  
    5. $array = ['q','w','e','r','t','y'];
    6. print_r($array);
    7.  
    8. $array = array_filter(
    9.   $array,
    10.   function ($key) {
    11.       return $key & 1;
    12.   }, ARRAY_FILTER_USE_KEY
    13. );
    14. print_r($array);