Вопрос по PHP

123
LEOnidUKG
На сайте с 25.11.2006
Offline
1723
#11

Если мне не изменяет память в PHP7 так уже нельзя делать.

✅ Мой Телеграм канал по SEO, оптимизации сайтов и серверов: https://t.me/leonidukgLIVE ✅ Качественное и рабочее размещение SEO статей СНГ и Бурж: https://getmanylinks.ru/
Solmyr
На сайте с 10.09.2007
Offline
501
#12
LEOnidUKG:
Долго это сколько миллисекунд?

Один проход примерно 0.0005-0.001с на реальных данных. То есть 500-1000 миллисекунд.

edogs software
На сайте с 15.12.2005
Offline
775
#13
doctorpc:
Не совсем понятно какие ключи выкидывать нужно. Почему имменно unset($arr['b'])? Т.к. b следующий элемент за текущим или какое-то другое условие?

Но если конкретно по этой задаче. То быстро пришли вот такие решения на ум:

Вариант 1:


$arr = array('a'=>'a','b'=>'b','c'=>'c');
foreach ($arr as $key =>&$vl) {
echo $key.'-'.$vl."\n";
if($vl=='a'){
unset($arr['b']);
}
}

В этом варианте неплохо бы в конец дописать unset($vl);

Иначе если потом кто-то напишет $vl='bug'; то в arr окажется a='a', c='bug'

Не то что бы это большая проблема (если пишешь код сам и следишь за повторным использованием переменных), но труднонаходимый баг если вдруг появится (особенно в большом коде - ищи потом почему вдруг массив изменился там где его вроде и не трогали).

Вообще при работе с указателями надо быть аккуратнее, в сях этому учат с рождения, а вот для пхп это почти "рокет саенс".

Разработка крупных и средних проектов. Можно с криптой. Разумные цены. Хорошее качество. Адекватный подход. Продаем lenovo legion в спб, дешевле магазинов, новые, запечатанные. Есть разные. skype: edogssoft
MK
На сайте с 18.08.2005
Offline
126
#14
doctorpc:
Не совсем понятно какие ключи выкидывать нужно

ага 😕

Удивительно, но первый вариант сработал. Спасибо огромное. Я три раза перечитал описание foreach, думал о таком решении, но не попробовал. Почему-то подумал что работать не будет. Сейчас попробовал - работает.

Тады и изначальный вариант работает, если массив нужен потом. ;)

$arr = array('a'=>'a','b'=>'b','c'=>'c');

foreach ($arr as $key =>$vl) { /* без ссылки на значение (&) */
if($vl=='a'){
unset($arr['b']);
}
if(isset($arr[$key])) echo $key.'-'.$vl."\n";
}

или

$arr = array('a'=>'a','b'=>'b','c'=>'c');

foreach ($arr as $key =>$vl) {
if($vl=='a'){
unset($arr['b']);
}
}
print_r($arr);
Если мне не изменяет память в PHP7 так уже нельзя делать.

Да и в 5+немного DEPRECATED

нет
doctorpc
На сайте с 12.07.2009
Offline
112
#15
LEOnidUKG:
Если мне не изменяет память в PHP7 так уже нельзя делать.

Спасибо, почитал об изменениях в PHP7.

foreach действительно переделали, но конкретно в этом случае если не ошибаюсь, изменений не произошло.

https://wiki.php.net/rfc/php7_foreach

Deletion of the next element referred by foreach pointer leads to skipping it (in the same way as as in PHP5).


$ sapi/cli/php -r '$a = [1,2,3]; foreach($a as &$v) {echo "$v\n"; unset($a[1]);}'
1
3


---------- Добавлено 25.02.2016 в 12:32 ----------

Marat_Kh:

Да и в 5+немного DEPRECATED

С передачей значений в функцию по ссылке не путаете?

Deprecated подобные конструкции:


randomFunction(&$param);
Solmyr
На сайте с 10.09.2007
Offline
501
#16
Marat_Kh:
Тады и изначальный вариант работает, если массив нужен потом.

Нужно с помощью unset сократить перебор

---------- Добавлено 26.02.2016 в 09:54 ----------

А еще такой вопрос. Если массив с числовыми ключами:

	
$arr = array('a','b','c');

foreach($arr as $key=>&$vl){
echo $key.'-'.$vl."\n";
if($vl=='a'){
unset($arr[1]);
}
}

То в данном случае, вариант doctorpc тоже работает точно как надо. Результат:

0-a

2-c

Можно ли ожидать что так и будет работать при изменениях версий PHP? Я именно имею ввиду момент, связанный с отличием в массивах php для числовых и для символьных ключей.

doctorpc
На сайте с 12.07.2009
Offline
112
#17
Solmyr:

Можно ли ожидать что так и будет работать при изменениях версий PHP? Я именно имею ввиду момент, связанный с отличием в массивах php для числовых и для символьных ключей.

Так в тут

я как раз такой пример и привел из документации PHP7.

Ничего в 7 версии касательно этого вопроса не меняется. Все должно работать независимо от того, ключ числовой или нет.

S7
На сайте с 15.08.2010
Offline
79
#18

Solmyr, вариант для любой версии php


$arr = array('a'=>'a', 'b'=>'b', 'c'=>'c');
$unset = false;
foreach($arr as $key => &$vl){
if ($unset) {
$vl = ''; // хотите - удаляйте значение, хотите - нет.
$unset = false;
continue;
}
echo $key.'-'.$vl."\n";
$unset = $vl=='a' ? true : false;
}
unset($vl); // удаляем ссылку
print_r(array_diff($arr, array(''))); // удаляем пустые значения
Оптимизайка
На сайте с 11.03.2012
Offline
396
#19
Solmyr:
Нужно итеративно проходя по массиву, выкидывать из него некоторые элементы, что должно сокращать итерацию

А почему вы считаете, что удаление элементов из массива ускорит итерацию? У вас внутри foreach долго выполняющийся код? Или вы пытаетесь сэкономить время на саму операцию foreach?

⭐ BotGuard (https://botguard.net) ⭐ — защита вашего сайта от вредоносных ботов, воровства контента, клонирования, спама и хакерских атак!
edogs software
На сайте с 15.12.2005
Offline
775
#20
Оптимизайка:
А почему вы считаете, что удаление элементов из массива ускорит итерацию? У вас внутри foreach долго выполняющийся код? Или вы пытаетесь сэкономить время на саму операцию foreach?

Дык у него же "стоит некая потребляющая много ресурса функция, которую нужно выполнять пореже."© которая выполняется на каждом элементе массива. Можно конечно не ансетить, а просто пропускать (вместо ансета создавая массив с элементами которые надо пропускать), но если весь массив дальше не нужен, то проще ансетить.

123

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий