array_replace_recursive意外删除数组值

时间:2015-01-28 17:58:41

标签: php arrays merge comparison

我需要为每个国家/地区提供一个阵列。周转。请在这里查看数组的结构,问题出现在数组结构之后。

结构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()用相同的值替换array1的值   来自以下所有数组的值。如果是第一个数组的一个键   存在于第二个数组中,其值将被该值替换   从第二个数组。如果密钥存在于第二个数组中,则不存在   第一个,它将在第一个数组中创建。 如果只有一个键   存在于第一个数组中,它将保持原样。如果有几个数组   通过更换,他们将按顺序处理,后者   数组覆盖以前的值。

简而言之,问题是:

  • 根据文档,我的错误在哪里?
  • 为什么array_replace_recursive会删除替换数组条目之间的日期?
  • 如何按照我需要的方式合并数组呢?

1 个答案:

答案 0 :(得分:1)

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方法,您可以在其中比较日期并根据需要进行替换。

假设您无法改变数组生成/存储的方式,您可以执行以下操作:

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);
}