为什么这在 JS 而不是 PHP 中有效


Why does this work in JS and not PHP?

不久

前在JS的编码学校做了一个项目,我们使用埃拉托色尼筛子(我不能不读出某种轰隆隆的回声(将所有质数输出到用户输入的数字。 我们为此想出的代码是:

JavaScript 代码示例

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中...

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++;

但是,即使它给了我一个输出,unsetarray_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 甚至以不同的方式处理unsetarray_splice,这可能是第一个问题的扩展(,这似乎是一件非常有价值的事情。

错误消息

这些在上面引用

注意:未定义的偏移量:2 英寸/用户/访客/桌面/测试/筛选.php 打开 23号线

警告:在/用户/来宾/桌面/测试/筛选.php 中除以零 18号线

警告:在/用户/来宾/桌面/测试/筛选.php 中除以零 18号线

警告:在/用户/来宾/桌面/测试/筛选.php 中除以零 18号线

警告:在/用户/来宾/桌面/测试/筛选.php 中除以零 18号线

注意:未定义的偏移量:4 英寸/用户/来宾/桌面/测试/筛选.php 打开 23号线

警告:在/用户/来宾/桌面/测试/筛选.php 中除以零 18号线

如此循环

往复...

编辑

我继续做了一些重新排列/格式化,以尝试更好地阐明这个问题。 这主要是对"一个悲伤的家伙"的回复的回应,他建议使用array_splice而不是unset。 这个推理似乎完全有道理,但我发现它似乎并没有达到预期的结果。

感谢任何花时间涉足此工作的人。 第一次尝试在这里得到答案,如果我让它变得比需要的更困难,我深表歉意。

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,或者重新组织你的代码。