大家好,我有一个关于PHP中数组和循环的问题。
对于我正在制作的游戏,我需要编写一个函数,它根据给定的大小和比率生成一堆水晶_id。
该比值是黑色晶体与不同颜色晶体的比值(因此,0,25 (1:4)和50的叠加将产生一个由40个黑色晶体和10个有色晶体组成的堆栈)。
我有所有的数学来计算每种颜色的晶体数量,但是我不知道如何用适当数量的彩色晶体来创建一个数组,其中每种颜色的代表都是相等的。
作为参考,代码从中选择的数组是一个名为$crystals_array的变量,它是一个由整数填充的数组,每个整数表示不同的有色晶体(例如,2、3、4、5、6)。
在上述情况下,我们有5种不同颜色的晶体,我们总共需要10种颜色的晶体,其中每个晶体都是相同的。所以我需要创建一个数组,它看起来有点像这样:
2,2,3,3,4,4,5,5,6,6
到目前为止,我的代码是:
for($i = 0; $i <= count($amount_crystals_color) - 1; $i++)
{
$array = array_fill(0, $amount_crystals_per_color_stack, $crystals_array[$i]);
$i++;
}使用上面的例子,$amount_crystals_per_color_stack等于2,amount_crystals_color等于5。
在执行此代码时,它输出一个数组: 2,2,这是我们需要多少2,但我不知道如何将剩余的晶体添加到这个数组中。
有人能帮我吗?
发布于 2018-01-20 15:09:38
您的代码有几个问题,我将分别讨论它们。
使用for 循环迭代数组的
您在代码中使用的是for循环,它具有以下循环头:
for($i = 0; $i <= count($crystals_array) - 1; $i++)循环由三个部分组成,每个部分由分号(;)分隔。
$i = 0是初始化部分。在这里,您初始化了一个变量,该变量后来用作迭代器,在每个循环迭代中都会发生变化。您也可以将此命名为起点。$i <= count($crystals_array) - 1是条件部分。形成一个条件,表示循环的迭代时间。只要表达式的计算结果为true,循环就会再次运行。因此,这个条件是在每次迭代开始时评估的。一旦条件计算为false,循环就会结束。因此,这部分也可以被命名端点。$i++是步长。这将在每次迭代结束时执行,并确定迭代器(在第一部分中定义的变量)将如何变化。$i++在此上下文中等于$i = $i + 1,表示步骤大小为1。因此,每次运行循环时,变量$i都会增加1。这就是说,您可以通过两个更改来改进和修复有关for循环的代码:
count()函数,然后在for循环的每一次迭代中再次计数数组。通过在$count = count($crystals_array);循环之前将其保存在变量for中并将条件更改为$i < $count,函数只会被调用一次,代码就会变得更快。$i。这是非常糟糕的代码风格。您将行$i++;添加到循环的末尾,但这已经在for头的步骤大小部分完成了。因为这也是在每次迭代中执行的,所以您将步骤大小增加到两个,这意味着您只使用$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);
}发布于 2018-01-20 14:54:31
正如我所理解的问题
$crystals_array = [2,3,4,5,6];
$amount_crystals_per_color_stack = 2;
$res = [];
foreach($crystals_array as $v) {
// repeat each item from array $amount_crystals_per_color_stack times
$res = array_merge($res, array_fill(0, $amount_crystals_per_color_stack, $v));
}
print_r($res); // [2,2,3,3,4,4,5,5,6,6]发布于 2018-01-20 14:57:36
您需要在循环的每一次迭代(repl在线)中合并数组,否则每次都会丢失结果。
比如:
$array = array();
for($i = 0; $i < count($amount_crystals_color); $i++)
{
$array = array_merge($array, array_fill(0, $amount_crystals_per_color_stack, $crystals_array[$i]);
}另外,您不需要循环中的$i++,因为如果条件是<而不是<=,则不需要循环两次,也不需要<=。
https://stackoverflow.com/questions/48357345
复制相似问题