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

Создание нового массива без дублей

Тема в разделе "PHP для новичков", создана пользователем MariaFilatova, 4 май 2020.

  1. MariaFilatova

    MariaFilatova Новичок

    С нами с:
    22 апр 2020
    Сообщения:
    7
    Симпатии:
    0
    Прошу помочь с заданием:
    есть массив в котором присутствуют дубли значений, нужно создать новый массив из старого, но чтобы не было дублей. Я нашла функцию, которая делает это автоматически. Хотелось бы узнать, как сделать это задание не прибегая к авто функции. Логика понятна, каждый элемент сравнивается со всеми остальными, но как это реализовать...

    PHP:
    1. //это используя функцию
    2. $fstAr = ['fst','snd','thd','fth','snd','thd'];
    3. $sndAr=[];
    4. $fstAr = ['fst','snd','thd','fth','snd','thd'];
    5. $sndAr=[];
    6.  
    7. //без функции получается бред...
    8.  
    9. $fstAr = ['fst','snd','thd','fth','snd','thd'];
    10. $sndAr=[];
    11. $x=1;
    12. foreach($fstAr as $value){
    13. $b=in_array($x,$fstAr);
    14. if($b!== $value) {
    15. array_push($sndAr, $value);
    16. }
    17. $x++;
    18. }
     
  2. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.750
    Симпатии:
    1.322
    Адрес:
    Лень
    PHP:
    1. <?php
    2.  
    3. declare ( strict_types = 1 );
    4.  
    5. error_reporting ( E_ALL );
    6.  
    7. $a = [ 5=>1,2,3,1,4,5,2,664=>1,2, null,777=>null ];
    8.  
    9. echo '#1' . PHP_EOL;
    10. var_dump ( array_unique ( $a ) );
    11.  
    12. echo '#2' . PHP_EOL;
    13. print_r ( array_flip ( array_flip ( $a ) ) ); # error Can only flip STRING and INTEGER values! null,777=>null
    14.  
    15. echo '#3' . PHP_EOL;
    16. print_r ( array_values ( array_flip ( array_flip ( $a ) ) ) ); # error Can only flip STRING and INTEGER values! null,777=>null
    17.  
    18. echo '#4' . PHP_EOL;
    19. print_r ( array_keys ( array_flip ( $a ) ) ); # error Can only flip STRING and INTEGER values! null,777=>null
    20.  
    21. $check = [];
    22.  
    23. $new = [];
    24.  
    25. foreach ( $a AS $k => $b )
    26. {
    27.     if ( ! array_key_exists ( $b, $check ) )
    28.     {
    29.         $check[$b] = $k;
    30.        
    31.         $new[$k] = $b;
    32.     }
    33. }
    34.  
    35. unset ( $check );
    36.  
    37. echo '#5' . PHP_EOL;
    38. print_r ( $new );
    PHP:
    1. #1
    2. array(6) {
    3.   [5]=>
    4.   int(1)
    5.   [6]=>
    6.   int(2)
    7.   [7]=>
    8.   int(3)
    9.   [9]=>
    10.   int(4)
    11.   [10]=>
    12.   int(5)
    13.   [666]=>
    14.   NULL
    15. }
    16. #2
    17. <br />
    18. <b>Warning</b>:  array_flip(): Can only flip STRING and INTEGER values! in <b>[...][...]</b> on line <b>11</b><br />
    19. <br />
    20. <b>Warning</b>:  array_flip(): Can only flip STRING and INTEGER values! in <b>[...][...]</b> on line <b>11</b><br />
    21. (
    22.     [664] => 1
    23.     [665] => 2
    24.     [7] => 3
    25.     [9] => 4
    26.     [10] => 5
    27. )
    28. #3
    29. <br />
    30. <b>Warning</b>:  array_flip(): Can only flip STRING and INTEGER values! in <b>[...][...]</b> on line <b>14</b><br />
    31. <br />
    32. <b>Warning</b>:  array_flip(): Can only flip STRING and INTEGER values! in <b>[...][...]</b> on line <b>14</b><br />
    33. (
    34.     [0] => 1
    35.     [1] => 2
    36.     [2] => 3
    37.     [3] => 4
    38.     [4] => 5
    39. )
    40. #4
    41. <br />
    42. <b>Warning</b>:  array_flip(): Can only flip STRING and INTEGER values! in <b>[...][...]</b> on line <b>17</b><br />
    43. <br />
    44. <b>Warning</b>:  array_flip(): Can only flip STRING and INTEGER values! in <b>[...][...]</b> on line <b>17</b><br />
    45. (
    46.     [0] => 1
    47.     [1] => 2
    48.     [2] => 3
    49.     [3] => 4
    50.     [4] => 5
    51. )
    52. #5
    53. (
    54.     [5] => 1
    55.     [6] => 2
    56.     [7] => 3
    57.     [9] => 4
    58.     [10] => 5
    59.     [666] =>
    60. )
    и тут нашелся казус.... откуда у меня ключ в массиве 666 ?
     
    MariaFilatova нравится это.
  3. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Это число зверя, @MouseZver )
     
    Dron-Boy нравится это.
  4. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.750
    Симпатии:
    1.322
    Адрес:
    Лень
    Вопрос с подвохом. Лично знаю почему.
     
  5. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Открыть документацию, посмотреть, что возвращает in_array не пробовала? А так, в правильном направлении мыслишь.
     
  6. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.750
    Симпатии:
    1.322
    Адрес:
    Лень
    in_array так же использует цикл for, и по сути будет воспроизводится данный цикл при каждой, новой итерации родительского цикла.
    https://stackoverflow.com/questions/19299508/how-can-i-check-if-given-int-exists-in-array
    PHP:
    1. template<class InputIt, class T>
    2. constexpr InputIt find(InputIt first, InputIt last, const T& value)
    3. {
    4.     for (; first != last; ++first) {
    5.         if (*first == value) {
    6.             return first;
    7.         }
    8.     }
    9.     return last;
    10. }
    --- Добавлено ---
    в инете пишут еще:
    PHP:
    1. in_array ищет за 6-9 сек ideone.com/Yb1mDa 6600ms
    2. а array_key_exists ищет тоже самое, но быстрее в 250(php5.6/py3.*) в 400+ раз (php7.3/py2.7)
     
  7. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    @MouseZver Это же учебное задание. В реальной программе любой нормальный человек пишет array_unique, и дело с концом.
     
  8. MariaFilatova

    MariaFilatova Новичок

    С нами с:
    22 апр 2020
    Сообщения:
    7
    Симпатии:
    0
    спасибо!
    --- Добавлено ---
    возвращает bool?
     
  9. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Угу. И почему ты ищешь какой-то x? Давайка, напиши словами, как должно работать всё. Просто русским языком. Но по порядку.
     
    MariaFilatova нравится это.
  10. MariaFilatova

    MariaFilatova Новичок

    С нами с:
    22 апр 2020
    Сообщения:
    7
    Симпатии:
    0
    я учусь первый месяц.. так что хочу понять как все работает...

    вот как я сделала

    PHP:
    1. $fstAr = ['fst','snd','thd','fth','snd','thd'];
    2. $sndAr=[];
    3. //$sndAr=array_unique($fstAr);
    4.  
    5. foreach ($fstAr as $value)
    6. {
    7.     if (in_array( $value, $sndAr ))
    8.     {
    9.         continue;
    10.        // $check[$value] = $key;
    11.  
    12.     }
    13.     else $sndAr[] = $value;
    14. }
    а есть другие способы? чтобы не вызывать новый массив в цикле? а чтобы
    брался первый элемент из первого массива и проверялся с остальными элементами, а потом бы добавлялся в новый массив и так далее?
    --- Добавлено ---
    ой... х я больше не ищу я поняла что ступила)) вот мой код сейчас:
    PHP:
    1. //creating new array without copies of older array values
    2. $fstAr = ['fst','snd','thd','fth','snd','thd'];
    3. $sndAr=[];
    4. //$sndAr=array_unique($fstAr);
    5.  
    6. foreach ($fstAr as $value)
    7. {
    8.     if (in_array( $value, $sndAr ))
    9.     {
    10.         continue;
    11.        // $check[$value] = $key;
    12.  
    13.     }
    14.     else $sndAr[] = $value;
    15. }
    16.  
    17.  
    18.  
    19. echo'<pre>';
    20. print_r($newAr);
    21. echo'<pre/>';
    22. echo "<br/>";
    все заработало!
    а есть другие способы? чтобы не вызывать новый массив в цикле? а чтобы
    брался первый элемент из первого массива и проверялся с остальными элементами, а потом бы добавлялся в новый массив и так далее?
     
  11. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Ну тут @MouseZver демонстрировал изыскания по переворачиванию массива - т.е., чтоб ключи стали значениями, значения ключами. Но это уже трюкачество, на мой взгляд. Можете почитать функции, которые он использовал - когда-нибудь где-нибудь пригодятся. По поводу скорости выполнения - не критично, в данном случае. Ну и конечно, если проект реальный, а не учебный, делается array_unique, которая на низком уровне отрабатывает наилучшим образом.
     
    MariaFilatova нравится это.
  12. MariaFilatova

    MariaFilatova Новичок

    С нами с:
    22 апр 2020
    Сообщения:
    7
    Симпатии:
    0
    я поняла...это задача из учебника. я хотела узнать, есть ли другой способ? например взять первый элемент в массиве и проверить его с другими элементами, потом второй элемент так же проверить?
     
  13. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Даже не задумывался, честно говоря... Ну так распиши по-русски другой способ по шагам, посмотри. Хотя, я всегда решаю самым простым способом задачу, а потом уже, если в процессе эксплуатации выясняется, что работает слишком медленно (и речь не про наносекунды, мы на php обычно не пишем проекты, где счёт на наносекунды), то начинаю оптимизировать
    --- Добавлено ---
    Тот же array_unique тоже не так часто используется, поскольку в реальных сайтах у нас данные обычно из базы, и у базы есть свой функционал, чтоб вернуть уникальные значения, и эффективнее заставить это сделать базу.
     
    MariaFilatova нравится это.
  14. MariaFilatova

    MariaFilatova Новичок

    С нами с:
    22 апр 2020
    Сообщения:
    7
    Симпатии:
    0
    да, скорее всего тот метод, что я хотела не получится. Я хотела брать элемент из массива, сравнивать его с остальными (но не с собой) и тогда уже вносить его в новый массив.
    вот так я думала:
    $fstAr = ['fst','snd','thd','fth','snd','thd'];
    берем fst и начинаем сравнивать с snd потом с thd...
    далее берем snd и начинаем сравнивать с fst потом с thd...

    Получается много лишнего кода?
     
  15. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    А потом на втором 'snd' ошибаемся :) Но за попытку расписать по-русски - огромный плюс. Всегда так делай, в любой непонятной ситуации.
     
    MariaFilatova нравится это.
  16. MariaFilatova

    MariaFilatova Новичок

    С нами с:
    22 апр 2020
    Сообщения:
    7
    Симпатии:
    0
    спасибо большое :) да, туплю дико))))