array_replace_recursive 意外删除数组值

array_replace_recursive unexpectedly deletes array values

我需要为每个国家/地区的营业额获取一个数组。请看这里数组的结构,问题在数组结构之后。

结构 1,$this->allTurnovers

array:5 [▼
  1 => array:54 [▶]
  2 => array:48 [▶]
  3 => array:52 [▶]
  4 => array:3 [▶]
  5 => array:6 [▶]
]

这里是$this->allTurnovers[5]折叠:

array:5 [▼
  1 => array:54 [▶]
  2 => array:48 [▶]
  3 => array:52 [▶]
  4 => array:3 [▶]
  5 => array:6 [▼
    0 => array:2 [▼
      "PurchaseDate" => "2014-12-08"
      "Amount" => "23.65"
    ]
    1 => array:2 [▼
      "PurchaseDate" => "2014-12-10"
      "Amount" => "14.91"
    ]
    2 => array:2 [▼
      "PurchaseDate" => "2014-12-15"
      "Amount" => "33.07"
    ]
    3 => array:2 [▼
      "PurchaseDate" => "2015-01-11"
      "Amount" => "14.99"
    ]
    4 => array:2 [▼
      "PurchaseDate" => "2015-01-17"
      "Amount" => "65.96"
    ]
    5 => array:2 [▼
      "PurchaseDate" => "2015-01-25"
      "Amount" => "25.52"
    ]
  ]
]

然后,我有一个包含给定时间内所有日期的数组,$this->allTimes:

array:54 [▼
  0 => array:2 [▼
    "PurchaseDate" => "2014-12-06"
    "Amount" => 0
  ]
  1 => array:2 [▼
    "PurchaseDate" => "2014-12-07"
    "Amount" => 0
  ]
  2 => array:2 [▼
    "PurchaseDate" => "2014-12-08"
    "Amount" => 0
  ]
  3 => array:2 [▼
    "PurchaseDate" => "2014-12-09"
    "Amount" => 0
  ]
  4 => array:2 [▼
    "PurchaseDate" => "2014-12-10"
    "Amount" => 0
  ]
  5 => array:2 [▼
    "PurchaseDate" => "2014-12-11"
    "Amount" => 0
  ]
  6 => array:2 [▼
    "PurchaseDate" => "2014-12-12"
    "Amount" => 0
  ]
  .....
  .....
  .....
  53 => array:2 [▼
    "PurchaseDate" => "2015-01-28"
    "Amount" => 0
   ]
]

我需要时间范围内每一天的日期和金额,因此我尝试将 $this->allTurnovers$this->AllTimes 结合使用。我用

做这个
array_replace_recursive();

函数如下:

public function getAll()
{
    $this->allTurnovers = (new GetTurnoverForAllParticipations())->run();
    $this->allTimes = (new MaxAndMinTimeForTurnoverChart())->getMinAndMax();

    foreach($this->allTurnovers as $turnover)
    {
        $replace[] = array_replace_recursive($this->allTimes, $turnover);
    }

    list($de,$fr,$uk,$es,$it) = $replace;

    $test = json_encode($it);
    dd($test);
}

$this->allTimes 最初为每个日期保留一个零数量,根据 $this->allTurnovers.

的数量替换

它似乎适用于框架内每天都有营业额的国家,但例如 $this->allTurnovers[5] 在框架内只有 6 天的营业额值。 json 编码输出是这样的:

"[{"PurchaseDate":"2014-12-08","Amount":"23.65"},{"PurchaseDate":"2014-12-10","Amount":"14.91"},{"PurchaseDate":"2014-12-15","Amount":"33.07"}.....

基本上,它去除了发生营业额的两个日期之间的所有日期。我真的不明白为什么会这样...

The documentation states

array_replace_recursive() replaces the values of array1 with the same values from all the following arrays. If a key from the first array exists in the second array, its value will be replaced by the value from the second array. If the key exists in the second array, and not the first, it will be created in the first array. If a key only exists in the first array, it will be left as is. If several arrays are passed for replacement, they will be processed in order, the later array overwriting the previous values.

简而言之,问题是:

array_replace_recursive() 方法如其所说。它正在根据数组键替换条目。这里的问题是你的阵列没有像你需要的那样键控。

$this->allTimes 是一个包含键 0、1、...、53 的数组。$this->allTurnovers[5] 是一个包含键 0、1、...、5 的数组。这为您提供以下结果:

$results = array_replace_recursive($this->allTimes, $this->allTurnovers[5]);

// equivalent to:

$results = array(
    0 => $this->allTurnovers[5][0],
    1 => $this->allTurnovers[5][1],
    2 => $this->allTurnovers[5][2],
    3 => $this->allTurnovers[5][3],
    4 => $this->allTurnovers[5][4],
    5 => $this->allTurnovers[5][5],
    6 => $this->allTimes[6],
    7 => $this->allTimes[7],
    ... => $this->allTimes[...],
    53 => $this->allTimes[53]
);

如果您使用日期重新键入数组,则此方法可行。但是,如果您不能这样做,则需要转到手动 foreach 方法,您可以在其中比较日期并根据需要进行替换。

假设您无法更改数组的方式 generated/stored,您可以这样做:

public function getAll()
{
    $this->allTurnovers = (new GetTurnoverForAllParticipations())->run();
    $this->allTimes = (new MaxAndMinTimeForTurnoverChart())->getMinAndMax();

    // PHP >= 5.5.0
    $keys = array_column($this->allTimes, 'PurchaseDate');
    // PHP < 5.5.0
    //$keys = array_map(function ($v) {
    //    return($v['PurchaseDate']);
    //}, $this->allTimes);
    $allTimes = array_combine($keys, $this->allTimes);

    foreach($this->allTurnovers as $turnover)
    {
        // PHP >= 5.5.0
        $keys = array_column($turnover, 'PurchaseDate');
        // PHP < 5.5.0
        //$keys = array_map(function ($v) {
        //    return($v['PurchaseDate']);
        //}, $turnover);
        $rekeyedTurnover = array_combine($keys, $turnover);

        $replace[] = array_replace_recursive($allTimes, $rekeyedTurnover);
        // use array_values() if you want to get rid of the date keys again
        //$replace[] = array_values(array_replace_recursive($allTimes, $rekeyedTurnover));
    }

    list($de,$fr,$uk,$es,$it) = $replace;

    $test = json_encode($it);
    dd($test);
}