Почему это работает в JS, а не в PHP?

Был проект в школе кодирования некоторое время назад в JS, где мы использовали Сито Эратосфена (Я не могу не читать это каким-то громким, эхом голосом), чтобы вывести все простые числа вплоть до введенного пользователем числа. Код, который мы придумали для этого:

var primeSifter = function(number) {
var numArray = numberList(number);
var prime = 2;
var count = 0;
while (prime <= number) {
numArray.forEach(function(num) {
if ((num !== prime) && (num % prime === 0)) {
numArray.splice(numArray.indexOf(num), 1);
}
});
count++;
prime = numArray[count];
}
return numArray;
}

Numberlist () это просто функция, которая создает массив чисел от 2 до любого числа, которое вводит пользователь.

count++;
prime = numArray[count];

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

В оригинальном, неотредактированном посте я использовал unset вместо array_splice, За ответом грустного парня я начал играть с ними обоими.

Этот код дает ошибки, показанные ниже, независимо от того, unset или же array_splice,

function number_list($input) {
$numList = array();
for ($i = 2; $i <= $input; $i++) {
array_push($numList, $i);
}
return $numList;
}

function sift_primes($input) {
$numArray = number_list($input);
$prime = 2;
$count = 0;
while ($prime <= $input) {
foreach ($numArray as $key => $num) {
if (($num !== $prime) && ($num % $prime === 0)) {
array_splice($numArray, $key, 1);
}
}
$count++;
$prime = $numArray[$count];
}
return $numArray;
}

Это то, что я изначально пришел сюда, чтобы выяснить: как эти две функции принципиально различаются в JS и PHP?


Следующее является своего рода расширением исходного вопроса:

Единственный способ, который я нашел, чтобы эта функция возвращала действительный вывод, это заменить:

$count++;
$prime = $numArray[$count];

С:

$prime++;

Однако даже когда это дает мне вывод, unset а также array_splice дай мне разные результаты.

Этот код выводит Array ( [0] => 2 [1] => 3 [2] => 5 [3] => 9 ), что не правильно, так как 9, очевидно, не простое число:

function sift_primes($input) {
$numArray = number_list($input);
$prime = 2;
$count = 0;
while ($prime <= $input) {
foreach ($numArray as $key => $num) {
if (($num !== $prime) && ($num % $prime === 0)) {
array_splice($numArray, $key, 1);
}
}
$prime++;
}
return $numArray;
}

Замена array_splice с unset($numArray[$key]) возвращает:
Array ( [0] => 2 [1] => 3 [3] => 5 [5] => 7 ), правильный ответ.

Вопрос НЕ «Как получить желаемый результат?» Я думаю, что я уже понял, как это сделать. Я действительно пытаюсь понять, что происходит за кулисами в обоих языках, чтобы сделать правильный подход в JS (первый блок кода выше) недопустимым в PHP (в частности, почему я не могу установить $prime быть следующим простым числом в массиве после объединения не простых чисел?). Кажется, что они обрабатывают сращивания по-разному на фундаментальном уровне (и, очевидно, PHP даже обрабатывает unset а также array_splice по-другому, что, возможно, является продолжением первого вопроса), что кажется действительно ценной вещью, которую нужно понять.

Это ссылки выше

Примечание: неопределенное смещение: 2 в /Users/Guest/Desktop/test/sift.php on
строка 23

Предупреждение: деление на ноль в /Users/Guest/Desktop/test/sift.php на
строка 18

Предупреждение: деление на ноль в /Users/Guest/Desktop/test/sift.php на
строка 18

Предупреждение: деление на ноль в /Users/Guest/Desktop/test/sift.php на
строка 18

Предупреждение: деление на ноль в /Users/Guest/Desktop/test/sift.php на
строка 18

Примечание: неопределенное смещение: 4 в /Users/Guest/Desktop/test/sift.php on
строка 23

Предупреждение: деление на ноль в /Users/Guest/Desktop/test/sift.php на
строка 18

И так далее, и так далее …

Я пошел дальше и немного перестроил / отформатировал, чтобы попытаться лучше сформулировать проблему. Это было главным образом в ответ на ответ «грустный чувак», в котором он предложил использовать array_splice вместо unset, Рассуждения, казалось, имели полный смысл, но я обнаружил, что они, похоже, не дают ожидаемого результата.

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

2

Решение

unset($a[idx]) больше похоже a[idx] = undefined чем splice,

Вы можете проверить себя:

$a = [0, 1, 2, 3];
unset($a[1]);
print_r($a);

Приведет к:

Array
(
[0] => 0
[2] => 2
[3] => 3
)

Так что взяв $prime = $numArray[$count]; вы попадете в те пустые места, которые будут преобразованы в 0 для операции разделения. Вы должны либо использовать array_spliceили реорганизовать свой код.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]