Подсчет или суммирование значений из одного многомерного ассоциативного массива с использованием другого - PullRequest
1 голос
/ 02 мая 2019

У меня есть два многомерных ассоциативных массива с одинаковыми ключами. Мне нужно посчитать / суммировать конкретные значения в одном массиве на основе требований другого массива.

Я пробовал вложенные циклы foreach, но не смог получить запрошенный результат. Я безуспешно искал Интернет в меру своих способностей.

Вот мой код, который не работал так, как было запрошено:

foreach ($b as $key => $value) {
  foreach ($a as $skey => $svalue) {
    if ($key == $skey) {
      foreach ($svalue[Season] as $ssvalue) {
        if ($value[Appearance] == $ssvalue) {
          $c[$key]['SeasonAppearances'][] = count($value[Appearance]);
        }
      }
    }
  }
}

1-й массив (извлечение) / $ a

$a = Array ( 
        [Paul] => Array ( 
                [Season] => Array ( 
                        [0] => 2014 
                        [1] => 2015 
                        [2] => 2016 
                        ) 
                ) 
        [John] => Array ( 
                [Season] => Array ( 
                        [0] => 2012 
                        ) 
                ) 
    )

2-й массив (извлечение) / $ b

$b = Array ( 
        [Paul] => Array ( 
                [Appearance] => Array ( 
                            [0] => 2014 
                            [1] => 2014 
                            [2] => 2014 
                            [3] => 2014 
                            [4] => 2014 
                            [5] => 2014 
                            [6] => 2014 
                            [7] => 2014 
                            [8] => 2015 
                            [9] => 2015 
                            [10] => 2015 
                            ) 
                ) 
        [John] => Array ( 
                [Appearance] => Array ( 
                            [0] => 2012 
                            [1] => 2012 
                            [2] => 2012 
                            [3] => 2012 
                            ) 
                ) 
        )

Запрошенный массив результатов / $ c

$c = Array ( 
        [Paul] => Array ( 
            [SeasonCounts] => Array ( 
                        [0] => 8 
                        [1] => 3 
                        [2] => 0 
                        ) 
            ) 
        [John] => Array ( 
            [SeasonCounts] => Array ( 
                        [0] => 4 
                        ) 
            ) 
    )

Я бы хотел посчитать количество появлений в $ b, соответствующих каждому человеку для каждого сезона в $ a, и создать массив результатов. Обратите внимание, что в 2016 году у Павла не было выступлений.

Ответы [ 2 ]

3 голосов
/ 03 мая 2019

Функциональный подход без условий: (* ​​1001 * Демо )

$season_data = [
    'Paul' => [
        'Season' => [2014, 2015, 2016]
    ],
    'John' => [
        'Season' => [2012]
    ]
];

$appearance_data = [
    'Paul' => [ 
        'Appearance'=> [
            2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2015, 2015, 2015 
        ]
    ],
    'John' => [
        'Appearance' => [
            2012, 2012, 2012, 2012 
        ]
    ]
];

foreach ($season_data as $person => $data) {
    $defaults = array_fill_keys($data['Season'], 0);
    $result[$person]['SeasonCounts'] = array_replace(
        $defaults,
        array_intersect_key(
            array_count_values($appearance_data[$person]['Appearance']),
            $defaults
        )
    );
}
var_export($result);

Выход:

array (
  'Paul' => 
  array (
    'SeasonCounts' => 
    array (
      2014 => 8,
      2015 => 3,
      2016 => 0,
    ),
  ),
  'John' => 
  array (
    'SeasonCounts' => 
    array (
      2012 => 4,
    ),
  ),
)

Использование функций для этой задачи поясняет выполняемые задачи - делает код легко понятным для будущих разработчиков.

  • Для каждого человека я временно сохраняю нужные годы с нулевым значением.
  • Затем я вызываю array_count_values(), чтобы быстро сгенерировать массив годов появления и их количества (это именно та задача, для которой была создана функция).
  • Затем отфильтруйте массив, чтобы сохранить только годы, назначенные в массиве сезона человека, с помощью array_intersect_key().
  • Наконец, замените все нули на их новые соответствующие значения счетчиков через array_replace().

В качестве небольшой модификации вышеприведенного, вы можете отфильтровать до , считая так: Демо .

Всего четыре функционально чистых, читаемых вызова функции на человека для достижения точного желаемого результата.

Мой массив результатов спроектирован с ассоциативными SeasonCounts подмассивами, потому что данные буквально ассоциативны. Сохранение выходных данных с индексированными счетами ослабляет взаимосвязь - этот подход можно избежать с помощью моего подхода.


В качестве альтернативы, вы можете сделать повторный фильтр и подсчитать количество вызовов для каждого случая сезона для каждого человека. ( Тот же результат )

foreach ($season_data as $person => $data) {
    foreach ($data['Season'] as $year) {
        $result[$person]['SeasonCounts'][$year] = sizeof(
            array_filter(
                $appearance_data[ $person]['Appearance'],
                function($v) use ($year) {
                    return $v == $year;
                })
            );
    }
}

Наконец, бесполезный, условно возрастающий подход. ( Тот же результат )

foreach ($season_data as $person => $data) {
    foreach ($data['Season'] as $year) {
        $result[$person]['SeasonCounts'][$year] = 0;
        foreach ($appearance_data[$person]['Appearance'] as $appearance) {
            if ($appearance == $year) {
                ++$result[$person]['SeasonCounts'][$year];
            }
        }
    }
}
0 голосов
/ 02 мая 2019

это должно считаться так, как вы хотите

$c = array();
$helper = array();
foreach ($b as $key => $value) {

    $c[$key] = array();
    $c[$key]["SeasonCount"] = array();
    $helper[$key] = array();
    foreach ($value["Appearance"] as $key1 => $value1) {

        $position = array_search($value1, $helper[$key]);
        if (false !== $position) {
            $c[$key]["SeasonCount"][$position]++;
        } else {
            $helper[$key][] = $value1;
            $c[$key]["SeasonCount"][] = 1;
        }

    }}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...