【问题标题】:How to loop though an array and create an array, in the loop, containing values from the original array?如何遍历一个数组并在循环中创建一个包含原始数组值的数组?
【发布时间】:2018-01-20 14:35:02
【问题描述】:

大家好,我有一个关于 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,但我不知道如何将剩余的晶体添加到该数组中。

谁能帮帮我?

【问题讨论】:

  • 你想复制你的数组元素,对吧??

标签: php arrays variables


【解决方案1】:

您的代码有几个问题,我将分别解决每个问题。

使用for 循环遍历数组

您在代码中使用了 for 循环,该循环具有以下循环头:

for($i = 0; $i <= count($crystals_array) - 1; $i++)

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

  1. 第一部分$i = 0是初始化部分。在这里,您初始化一个变量,该变量稍后用作迭代器,它将在每次循环迭代中更改。您也可以将其命名为起点。
  2. 第二部分$i &lt;= count($crystals_array) - 1是条件部分。形成一个条件,该条件应表示循环将迭代多长时间。只要表达式的计算结果为真,循环就会再次运行。因此,在每次迭代开始时都会评估此条件。一旦条件评估为假,循环就会结束。因此这部分也可以命名为端点。
  3. 第三部分$i++是步长。这在每次迭代结束时执行,并确定迭代器(您在第一部分中定义的变量)将如何更改。 $i++在此上下文中等于 $i = $i + 1,表示步长为 1。因此,变量 $i 每次循环运行都会增加 1。

也就是说,您可以通过以下两项更改来改进和修复有关 for 循环的代码:

  1. 将在条件部分执行的函数保存到变量中,前提是它们为每次迭代返回一个常量结果。您使用count() 函数,该函数将为for 循环的每次迭代再次计算您的数组。通过在 for 循环之前将其保存在变量 $count = count($crystals_array); 中并将条件更改为 $i &lt; $count,该函数只被调用一次,并且您的代码变得更快。
  2. 不要在循环头之外更改迭代器变量$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);
}

【讨论】:

  • 非常感谢您提供令人难以置信的详细解释。作为一个新手程序员,目前正在学习这样的 CS 东西真的很有帮助。我最终使用了另一位评论者提供的代码,但我想感谢您花费时间编写此代码。
【解决方案2】:

据我了解问题

$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]

【讨论】:

  • 工作就像一个魅力。非常感谢!
【解决方案3】:

您需要在循环的每次迭代中合并您的数组 (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++,否则它会迭代两次,如果条件是&lt; 而不是&lt;=,则不需要count(..)-1

【讨论】:

    【解决方案4】:

    您可以使用简单的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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 2021-08-07
      • 2013-11-06
      相关资源
      最近更新 更多