PHP: накапливать значения в ассоциативном массиве - PullRequest
0 голосов
/ 13 мая 2019

Я хотел бы накапливать значения в ассоциативном массиве в зависимости от части ключа.

Я проверил этот цикл foreach, который отлично работает в индексированном массиве:

$b = array();

foreach ($a as $key => $value) {
  if ($key > 0) {
    $b[$key] = $b[$key - 1] + $value;
  }
}

Iне может заставить его работать в ассоциативном массиве, хотя ...

$a (отрывок)

Array ( 
    [2014-04-22|Paul] => 0 
    [2014-04-28|Paul] => 2 
    [2014-05-13|Paul] => 0
    [2014-06-03|Paul] => 1 
    [2014-06-12|Paul] => 0 
    [2014-08-11|Paul] => 1 
    [2014-08-28|Paul] => 3 
    [2012-05-09|John] => 1 
    [2012-08-29|John] => 2 
    [2012-09-05|John] => 0 
    [2012-09-13|John] => 1 
)

$b (желаемый результат)

Array ( 
    [2014-04-22|Paul] => 0 
    [2014-04-28|Paul] => 2 
    [2014-05-13|Paul] => 2 
    [2014-06-03|Paul] => 3 
    [2014-06-12|Paul] => 3 
    [2014-08-11|Paul] => 4 
    [2014-08-28|Paul] => 7 
    [2012-05-09|John] => 1 
    [2012-08-29|John] => 3 
    [2012-09-05|John] => 3 
    [2012-09-13|John] => 4 
)

В желаемом результате каждое значение равно «Павлу», а «Иоанн» (и более) суммируется с предыдущим.

Ответы [ 2 ]

0 голосов
/ 13 мая 2019

Вы можете сделать это, отслеживая названия частей клавиш и сбрасывая общее количество, когда вы получите новое имя:

$b = array();
$lastname = '';
foreach ($a as $key => $value) {
    list($d, $n) = explode('|', $key);
    if ($n == $lastname) {
        $total += $value;
    }
    else {
        $total = $value;
    }
    $b[$key] = $total;
    $lastname = $n;
}
print_r($b);

Выход:

Array ( 
    [2014-04-22|Paul] => 0 
    [2014-04-28|Paul] => 2 
    [2014-05-13|Paul] => 2 
    [2014-06-03|Paul] => 3 
    [2014-06-12|Paul] => 3 
    [2014-08-11|Paul] => 4 
    [2014-08-28|Paul] => 7 
    [2012-05-09|John] => 1 
    [2012-08-29|John] => 3 
    [2012-09-05|John] => 3 
    [2012-09-13|John] => 4 
)

Демонстрация на 3v4l.org

0 голосов
/ 13 мая 2019

Используя array_walk , проверьте, совпадает ли текущее имя со следующим именем, согласно которому я сбрасываю значение следующим.

$result = [];
$tempKey = '';
$arr = array_walk($arr, function($item, $key) use(&$result, &$tempKey, &$total){
    list($date, $name) = explode("|", $key); // explode key
    if(empty($tempKey) || $tempKey != $name){ // if empty or if conflict
        $tempKey = $name; // tempKey for reference
        $total = $item; // total reset to current value
    }else{
        $total += $item; // adding for same name
    }
    $result[$key] = $total; // putting calculated value
});

print_r($result);

Вывод

Array
(
    [2014-04-22|Paul] => 0
    [2014-04-28|Paul] => 2
    [2014-05-13|Paul] => 2
    [2014-06-03|Paul] => 3
    [2014-06-12|Paul] => 3
    [2014-08-11|Paul] => 4
    [2014-08-28|Paul] => 7
    [2012-05-09|John] => 1
    [2012-08-29|John] => 3
    [2012-09-05|John] => 3
    [2012-09-13|John] => 4
)

Демо .

...