Прошу помочь с заданием: есть массив в котором присутствуют дубли значений, нужно создать новый массив из старого, но чтобы не было дублей. Я нашла функцию, которая делает это автоматически. Хотелось бы узнать, как сделать это задание не прибегая к авто функции. Логика понятна, каждый элемент сравнивается со всеми остальными, но как это реализовать... PHP: //это используя функцию $fstAr = ['fst','snd','thd','fth','snd','thd']; $sndAr=[]; $fstAr = ['fst','snd','thd','fth','snd','thd']; $sndAr=[]; //без функции получается бред... $fstAr = ['fst','snd','thd','fth','snd','thd']; $sndAr=[]; $x=1; foreach($fstAr as $value){ $b=in_array($x,$fstAr); if($b!== $value) { array_push($sndAr, $value); } $x++; }
PHP: <?php declare ( strict_types = 1 ); error_reporting ( E_ALL ); $a = [ 5=>1,2,3,1,4,5,2,664=>1,2, null,777=>null ]; echo '#1' . PHP_EOL; var_dump ( array_unique ( $a ) ); echo '#2' . PHP_EOL; print_r ( array_flip ( array_flip ( $a ) ) ); # error Can only flip STRING and INTEGER values! null,777=>null echo '#3' . PHP_EOL; print_r ( array_values ( array_flip ( array_flip ( $a ) ) ) ); # error Can only flip STRING and INTEGER values! null,777=>null echo '#4' . PHP_EOL; print_r ( array_keys ( array_flip ( $a ) ) ); # error Can only flip STRING and INTEGER values! null,777=>null $check = []; $new = []; foreach ( $a AS $k => $b ) { if ( ! array_key_exists ( $b, $check ) ) { $check[$b] = $k; $new[$k] = $b; } } unset ( $check ); echo '#5' . PHP_EOL; print_r ( $new ); PHP: #1 array(6) { [5]=> int(1) [6]=> int(2) [7]=> int(3) [9]=> int(4) [10]=> int(5) [666]=> NULL } #2 <br /> <b>Warning</b>: array_flip(): Can only flip STRING and INTEGER values! in <b>[...][...]</b> on line <b>11</b><br /> <br /> <b>Warning</b>: array_flip(): Can only flip STRING and INTEGER values! in <b>[...][...]</b> on line <b>11</b><br /> Array ( [664] => 1 [665] => 2 [7] => 3 [9] => 4 [10] => 5 ) #3 <br /> <b>Warning</b>: array_flip(): Can only flip STRING and INTEGER values! in <b>[...][...]</b> on line <b>14</b><br /> <br /> <b>Warning</b>: array_flip(): Can only flip STRING and INTEGER values! in <b>[...][...]</b> on line <b>14</b><br /> Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 ) #4 <br /> <b>Warning</b>: array_flip(): Can only flip STRING and INTEGER values! in <b>[...][...]</b> on line <b>17</b><br /> <br /> <b>Warning</b>: array_flip(): Can only flip STRING and INTEGER values! in <b>[...][...]</b> on line <b>17</b><br /> Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 ) #5 Array ( [5] => 1 [6] => 2 [7] => 3 [9] => 4 [10] => 5 [666] => ) и тут нашелся казус.... откуда у меня ключ в массиве 666 ?
Открыть документацию, посмотреть, что возвращает in_array не пробовала? А так, в правильном направлении мыслишь.
in_array так же использует цикл for, и по сути будет воспроизводится данный цикл при каждой, новой итерации родительского цикла. https://stackoverflow.com/questions/19299508/how-can-i-check-if-given-int-exists-in-array PHP: template<class InputIt, class T> constexpr InputIt find(InputIt first, InputIt last, const T& value) { for (; first != last; ++first) { if (*first == value) { return first; } } return last; } --- Добавлено --- в инете пишут еще: PHP: in_array ищет за 6-9 сек ideone.com/Yb1mDa 6600ms а array_key_exists ищет тоже самое, но быстрее в 250(php5.6/py3.*) в 400+ раз (php7.3/py2.7)
@MouseZver Это же учебное задание. В реальной программе любой нормальный человек пишет array_unique, и дело с концом.
Угу. И почему ты ищешь какой-то x? Давайка, напиши словами, как должно работать всё. Просто русским языком. Но по порядку.
я учусь первый месяц.. так что хочу понять как все работает... вот как я сделала PHP: $fstAr = ['fst','snd','thd','fth','snd','thd']; $sndAr=[]; //$sndAr=array_unique($fstAr); foreach ($fstAr as $value) { if (in_array( $value, $sndAr )) { continue; // $check[$value] = $key; } else $sndAr[] = $value; } а есть другие способы? чтобы не вызывать новый массив в цикле? а чтобы брался первый элемент из первого массива и проверялся с остальными элементами, а потом бы добавлялся в новый массив и так далее? --- Добавлено --- ой... х я больше не ищу я поняла что ступила)) вот мой код сейчас: PHP: //creating new array without copies of older array values $fstAr = ['fst','snd','thd','fth','snd','thd']; $sndAr=[]; //$sndAr=array_unique($fstAr); foreach ($fstAr as $value) { if (in_array( $value, $sndAr )) { continue; // $check[$value] = $key; } else $sndAr[] = $value; } echo'<pre>'; print_r($newAr); echo'<pre/>'; echo "<br/>"; все заработало! а есть другие способы? чтобы не вызывать новый массив в цикле? а чтобы брался первый элемент из первого массива и проверялся с остальными элементами, а потом бы добавлялся в новый массив и так далее?
Ну тут @MouseZver демонстрировал изыскания по переворачиванию массива - т.е., чтоб ключи стали значениями, значения ключами. Но это уже трюкачество, на мой взгляд. Можете почитать функции, которые он использовал - когда-нибудь где-нибудь пригодятся. По поводу скорости выполнения - не критично, в данном случае. Ну и конечно, если проект реальный, а не учебный, делается array_unique, которая на низком уровне отрабатывает наилучшим образом.
я поняла...это задача из учебника. я хотела узнать, есть ли другой способ? например взять первый элемент в массиве и проверить его с другими элементами, потом второй элемент так же проверить?
Даже не задумывался, честно говоря... Ну так распиши по-русски другой способ по шагам, посмотри. Хотя, я всегда решаю самым простым способом задачу, а потом уже, если в процессе эксплуатации выясняется, что работает слишком медленно (и речь не про наносекунды, мы на php обычно не пишем проекты, где счёт на наносекунды), то начинаю оптимизировать --- Добавлено --- Тот же array_unique тоже не так часто используется, поскольку в реальных сайтах у нас данные обычно из базы, и у базы есть свой функционал, чтоб вернуть уникальные значения, и эффективнее заставить это сделать базу.
да, скорее всего тот метод, что я хотела не получится. Я хотела брать элемент из массива, сравнивать его с остальными (но не с собой) и тогда уже вносить его в новый массив. вот так я думала: $fstAr = ['fst','snd','thd','fth','snd','thd']; берем fst и начинаем сравнивать с snd потом с thd... далее берем snd и начинаем сравнивать с fst потом с thd... Получается много лишнего кода?
А потом на втором 'snd' ошибаемся Но за попытку расписать по-русски - огромный плюс. Всегда так делай, в любой непонятной ситуации.