您的代码有几个问题,我将分别解决每个问题。
使用for 循环遍历数组
您在代码中使用了 for 循环,该循环具有以下循环头:
for($i = 0; $i <= count($crystals_array) - 1; $i++)
循环由三个部分组成,每个部分用分号 (;) 分隔。
- 第一部分
$i = 0是初始化部分。在这里,您初始化一个变量,该变量稍后用作迭代器,它将在每次循环迭代中更改。您也可以将其命名为起点。
- 第二部分
$i <= count($crystals_array) - 1是条件部分。形成一个条件,该条件应表示循环将迭代多长时间。只要表达式的计算结果为真,循环就会再次运行。因此,在每次迭代开始时都会评估此条件。一旦条件评估为假,循环就会结束。因此这部分也可以命名为端点。
- 第三部分
$i++是步长。这在每次迭代结束时执行,并确定迭代器(您在第一部分中定义的变量)将如何更改。 $i++在此上下文中等于 $i = $i + 1,表示步长为 1。因此,变量 $i 每次循环运行都会增加 1。
也就是说,您可以通过以下两项更改来改进和修复有关 for 循环的代码:
- 将在条件部分执行的函数保存到变量中,前提是它们为每次迭代返回一个常量结果。您使用
count() 函数,该函数将为for 循环的每次迭代再次计算您的数组。通过在 for 循环之前将其保存在变量 $count = count($crystals_array); 中并将条件更改为 $i < $count,该函数只被调用一次,并且您的代码变得更快。
- 不要在循环头之外更改迭代器变量
$i。这是非常糟糕的代码风格。您将行 $i++; 添加到循环的末尾,但这已经在 for 标头的步长部分完成。因为这也是在每次迭代的 and 时执行的,所以您将步长增加到了 2,这意味着您只使用 $i = 0、$i = 2 和 $i = 4 运行 for 循环,而不是为每个元素运行。
对于您的代码,$i 迭代器的使用仅用于处理初始数组的元素。即使您将来应该了解for 循环,您也应该在这种情况下使用foreach 循环。以下代码相当于您的 for 循环。
//This code still contains another major bug and is jsut a partial improvvement
foreach($crystals_array as $crystal) {
$array = array_fill(0, $amount_crystals_per_color_stack, $crystal);
}
如您所见,您无需担心计算初始数组,也无需担心当前值在哪个索引中。相反,变量$crystal 将自动包含每次迭代的下一个元素。
向数组添加元素
您使用以下行将新生成的元素保存在数组中:
$array = array_fill(0, $amount_crystals_per_color_stack, $crystal);
如果您仔细观察,您会在行首使用带有$array = 的标准赋值。这意味着(与每个变量赋值一样)变量的先前值被赋值右侧提供的新值覆盖。您不想要的是覆盖数组,而是在其上附加一些内容。
这可以通过在变量名的末尾添加两个方括号来完成:$array[] = ...。现在,如果变量$array 真的是一个数组,那么赋值右侧的任何值都将附加到数组中,而不是覆盖它。
以正确的方式管理结果类型
以下行仍然包含一个主要问题:
$array[] = array_fill(0, $amount_crystals_per_color_stack, $crystal);
array_fill() 的结果类型本身就是一个数组。通过将其附加到前一个数组,您将获得以下结构:
$array = [
[2, 2],
[3, 3],
[4, 4],
[5, 5],
[6, 6],
];
如您所见,代码完全按照它应该做的,但不是您想要的。每个结果(数组)都附加到数组中。因此,结果是一个或多个数组(或多维数组)。相反,您想要的是将结果的值附加到现有数组中。
PHP 为此提供了一个名为array_merge() 的函数。此函数获取一个(或多个)数组的所有元素,并将它们附加到第一个数组的末尾,该数组是给函数的。您可以按如下方式使用它:
$newCrystals = array_fill(0, $amount_crystals_per_color_stack, $crystal);
$array = array_merge($array, $newCrystals);
如您所见,后一行再次包含一个正常的赋值。 ($array =) 这是因为array_merge() 不会修改给它的第一个数组,而是创建一个包含合并字段的新数组。因此,新数组包含旧数组中的所有值,用它覆盖旧数组是安全的。
因此完整的代码是:
$array = [];
foreach($crystals_array as $crystal) {
$newCrystals = array_fill(0, $amount_crystals_per_color_stack, $crystal);
$array = array_merge($array, $newCrystals);
}