大家好我对PHP中的数组和循环有疑问。
对于我正在制作的游戏,我需要编写一个函数,根据给定的大小和比例生成一堆crystal_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个,但我无法弄清楚如何将剩余的晶体添加到此数组中。
任何人都可以帮助我吗?
答案 0 :(得分:0)
我理解这个问题
$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]
答案 1 :(得分:0)
您需要在循环的每次迭代(repl online)中合并您的数组,否则每次都会丢失结果。
像:
$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++
,因为否则会迭代两次,如果条件为count(..)-1
而不是{{1},则不需要<
}}
答案 2 :(得分:0)
您可以使用简单foreach()
来实现此目标 -
$amount_crystals_per_color_stack = 2;
$array = [2,3,4,5,6];
$result = array();
foreach($array as $a){
for($i=1;$i<=$amount_crystals_per_color_stack;$i++){
array_push($result, $a);
}
}
print_r($result);
答案 3 :(得分:0)
您的代码存在一些问题,我将逐一解决每个问题。
使用for
循环迭代数组
您在代码中使用了for循环,它具有以下循环头:
for($i = 0; $i <= count($crystals_array) - 1; $i++)
循环由三部分组成,每部分用分号(;
)分隔。
$i = 0
是初始化部分。在这里初始化一个变量,后来用作迭代器,它将在每次循环迭代中改变。您也可以将此命名为起点。$i <= count($crystals_array) - 1
是条件部分。形成一个条件,表示循环应迭代多长时间。只要表达式的计算结果为true,循环就会再次运行。因此,在每次迭代开始时评估该条件。一旦条件评估为假,循环就会结束。因此,该部分也可以命名为端点。$i++
是步长。这在每次迭代结束时执行,并确定迭代器(您在第一部分中定义的变量)的变化方式。 $i++
在此上下文中 等于$i = $i + 1
并表示步长为1.因此,对于每次循环运行,变量$i
会增加1。 这就是说,您可以通过两个更改来改进和修复有关for
循环的代码:
count()
函数,然后在for
循环的每次迭代中再次计算您的数组。通过在$count = count($crystals_array);
循环之前将其保存在变量for
中并将条件更改为$i < $count
,该函数仅被调用一次,您的代码变得更快。$i
。这是非常糟糕的代码风格。您已将行$i++;
添加到循环的末尾,但这已在for
标题的步长部分中完成。因为这是在每次迭代和每次迭代时执行的,所以您将步长增加到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);
}