如何从一维数组创建具有关联子数组的数组?

时间:2018-09-07 07:50:30

标签: php arrays multidimensional-array associative-array

我有以下数组。

Array(
[1041] => 30
[1046] => 10
[1047] => 10
)

我想像下面那样存储它。

Array([0] => Array
(
    [material_name] => 1041
    [material_qty] => 30
) 
[1] => Array
(
    [material_name] => 1046
    [material_qty] => 10
)
[2] => Array
(
    [material_name] => 1047
    [material_qty] => 10
) )

现在我正在尝试存储键值,但它只存储最后一个。

for($i=0; $i<count($materials); $i++){
              foreach($materials as $key => $value){
                 $dataArrMaterial[$i] = array(
                        'material_name' => $key,
              'material_qty' => $value
                         );
              } }
              _print($dataArrMaterial);

我的输出正在跟踪。

Array(
[0] => Array
    (
        [material_name] => 1047
        [material_qty] => 10
    )

[1] => Array
    (
        [material_name] => 1047
        [material_qty] => 10
    )

[2] => Array
    (
        [material_name] => 1047
        [material_qty] => 10
    ) )

现在请帮助我做到这一点。 预先感谢。

2 个答案:

答案 0 :(得分:1)

您可以简化很多事情:

<?php

namespace App\Traits;

use Exception;

/**
 * Trait OrCreateTrait
 */
trait OrCreateTrait
{
    /**
     * @param array $attributes
     * @param array $values
     *
     * @return mixed
     */
    public static function updateOrCreate(array $attributes, array $values = [])
    {
        return static::tryManyTimes(function () use ($attributes, $values) {
            return (new static)->newQuery()->updateOrCreate($attributes, $values);
        });
    }

    /**
     * @param array $attributes
     * @param array $values
     *
     * @return mixed
     */
    public static function firstOrCreate(array $attributes, array $values = [])
    {
        return static::tryManyTimes(function () use ($attributes, $values) {
            return (new static)->newQuery()->firstOrCreate($attributes, $values);
        });
    }

    /**
     * @param callable $callback
     *
     * @return mixed
     */
    private static function tryManyTimes(callable $callback)
    {
        try {
            $output = $callback();
        } catch (Exception $e) {
            try {
                $output = $callback();
            } catch (Exception $e) {
                usleep(10000);
                try {
                    $output = $callback();
                } catch (Exception $e) {
                    usleep(100000);
                    try {
                        $output = $callback();
                    } catch (Exception $e) {
                        usleep(250000);
                        try {
                            $output = $callback();
                        } catch (Exception $e) {
                            $output = null;
                        }
                    }
                }
            }
        }
        return $output;
    }
}

答案 1 :(得分:0)

由于没有向您解释为什么为什么,我会的。

for($i=0; $i<count($materials); $i++){
    foreach($materials as $key => $value){
        // the value of $i is not changed within this loop
        $dataArrMaterial[$i] = array('material_name' => $key, 'material_qty' => $value);
    }
    // when the for() loop starts again, $i is incremented
}

因此,在foreach循环的第一次迭代中,您正在将所有子数组分配给相同的$i键(0)。 1041循环后,您的输出数组如下所示:

[0 => ["material_name" => 1041, "material_qty" => 30]];

1046之后,第一个推送的子数组将被覆盖,因为同一级别上的键必须唯一。

[0 => ["material_name" => 1046, "material_qty" => 10]];

然后,第三个元素覆盖输出数组中的第二个元素:

[0 => ["material_name" => 1047, "material_qty" => 10]];

一旦内部循环(foreach)完成,外部循环(for)就会增加$i,并且对于“ 1”键,将重复执行“覆盖”过程输出数组。然后再一次因为count($materials) = 3(三个迭代)。

这是为什么 ,您将像这样重复获得最后一组值:

[0 => ["material_name" => 1047, "material_qty" => 10]];
[1 => ["material_name" => 1047, "material_qty" => 10]];
[2 => ["material_name" => 1047, "material_qty" => 10]];

关于执行此任务的最佳方法,您可以使用我重复的链接中的解决方案,也可以按照Arkascha的说明进行操作。