foreach и continue

cyborg

Новичок
PHP:
$array = array(
 '0' => '0',
 '1' => '1',
 '2' => '2',
 't' => 't',

);

foreach($array as $k => $v) {
  if($k=='t') continue;
  echo "$k: $v\n";
}
почему не выводится элемент массива $array['0'] ?
 

Вурдалак

Продвинутый новичок
Потому что это это PHP. Строка '0' приводится к числу 0 в индексе массива, дальше уже происходит магия сравнения числа и строки.
 

cyborg

Новичок
Дык если пытаться пропустить что-то другое, то нулевой элемент выводится.
Например так:

if($k==1) continue;

Выведется все, кроме 1 элемента. А при сравнении c t вывод отрубает начисто
 

Hello

Новичок
cyborg, http://php.net/manual/en/language.types.array.php
Strings containing valid integers will be cast to the integer type.
В итоге происходит сравнение
PHP:
if(0=='t') continue;
А при сравнение числа со строкой происходит преобразование в число. Т.к. 't' не содержит чисел в начале, то преобразуется тоже в 0
Получаем условие
PHP:
if(0==0) continue;
 

MiksIr

miksir@home:~$
Вот интересно чем руководствовались при создании такой конвертации. Почему строку в число, а не число в строку в случае не числовой строки....
 

С.

Продвинутый новичок
Может потому, что число в виде строки -- это нормально и естественно , а строки в виде числа -- не очень.
 

Фанат

oncle terrible
Команда форума
Я занимался этим вопросом в свое время.
В пхп нет отдельной функции для оператора ==
А есть одна функция сравнения сразу на три оператора
На вход подаются два значения, а на выходе -1, 0, 1
Что означает, соответственно, меньше, равно, больше.

И если для == приводить к числу не надо, то для <> это критически необходимо.
 
Последнее редактирование:

MiksIr

miksir@home:~$
< > можно и со строками делать, и оно в общем работает "a" < "b"
 

MiksIr

miksir@home:~$
Да не, речь о том, что трансляция 5 == "a" более логично выглядит в "5" == "a", а не в 5 == 0, как сейчас.
 

Фанат

oncle terrible
Команда форума
Она не может быть "5" == "a" потому что для < обязана быть 5 < 0
 

MiksIr

miksir@home:~$
И кто обязал 5 быть меньше нуля? Не понимаю о чем речь. Ну будет 5 < "a" как "5" < "a", и что?
 

MiksIr

miksir@home:~$
Не, если is_numeric с обоих сторон - переводим в числа, если хотя бы с одной стороны невалидное число - сравниваем как строки.
Такая логика мне кажется менее подвержена нежданчикам.
 

Фанат

oncle terrible
Команда форума
Валидность чисел - вещь субьективная.
Пробел после числа делает его невалидным?
 

Вурдалак

Продвинутый новичок
Не, если is_numeric с обоих сторон - переводим в числа, если хотя бы с одной стороны невалидное число - сравниваем как строки.
Код:
$ php -r 'for ($i = -2147483648, $m = 2147483647, $k = 0; $i < $m; $i++) if (is_numeric(pack("N", $i))) {$k++;} var_dump($k);'
int(40672)
Если считать, что мы сравниваем случайные числа в big endian без unpack'а напрямую оператором <, то в 0.000000008967% случаев будет нежданчик в виде сравнения бинарей как чисел, записанных ASCII-символами. Но какой процент из них будет отличаться от «правильного» сравнения мы пока сказать не можем, нам нужно больше денег на исследования. В свою очередь это может привести к катастрофическим последствиям, когда на больших объемах данных через несколько лет произойдёт неправильное сравнение, которое повлечет за собой непланирумый запуск ракеты в сторону Китая.

Теперь этой бесполезной информацией обладаете и вы.
 
Последнее редактирование:

MiksIr

miksir@home:~$
Если считать, что мы сравниваем случайные числа в big endian без unpack'а напрямую оператором <, то в 0.000000008967% случаев будет нежданчик в виде сравнения бинарей как чисел, записанных ASCII-символами.
Предполагается, что сам интерпретатор знает тип данных - string это или integer. По-этому при сравнении integer с integer никаких нежданчиков быть не должно. А вот сравнение integer со string при расчетах траектории ракет не используется, так что Китай может спасть спокойно, а деньги можно пропить.
 
Сверху