如何循环数组并在循环中创建一个包含原始数组值的数组?

时间:2018-01-20 14:35:03

标签: php arrays variables

大家好我对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个,但我无法弄清楚如何将剩余的晶体添加到此数组中。

任何人都可以帮助我吗?

4 个答案:

答案 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++)

循环由三部分组成,每部分用分号(;)分隔。

  1. 第一部分$i = 0是初始化部分。在这里初始化一个变量,后来用作迭代器,它将在每次循环迭代中改变。您也可以将此命名为起点。
  2. 第二部分$i <= count($crystals_array) - 1是条件部分。形成一个条件,表示循环应迭代多长时间。只要表达式的计算结果为true,循环就会再次运行。因此,在每次迭代开始时评估该条件。一旦条件评估为假,循环就会结束。因此,该部分也可以命名为端点。
  3. 第三部分$i++是步长。这在每次迭代结束时执行,并确定迭代器(您在第一部分中定义的变量)的变化方式。 $i++在此上下文中 等于$i = $i + 1并表示步长为1.因此,对于每次循环运行,变量$i会增加1。
  4. 这就是说,您可以通过两个更改来改进和修复有关for循环的代码:

    1. 将在条件部分中执行的函数保存到变量中,如果它们为每次迭代返回一个常量结果。您使用count()函数,然后在for循环的每次迭代中再次计算您的数组。通过在$count = count($crystals_array);循环之前将其保存在变量for中并将条件更改为$i < $count,该函数仅被调用一次,您的代码变得更快。
    2. 不要在循环标题之外更改迭代器变量$i。这是非常糟糕的代码风格。您已将行$i++;添加到循环的末尾,但这已在for标题的步长部分中完成。因为这是在每次迭代和每次迭代时执行的,所以您将步长增加到2,这意味着您只使用$i = 0$i = 2$i = 4运行for循环,而不是每个元件。
    3. 对于您的代码,$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);
      }