WedX - журнал о программировании и компьютерных науках

Сумма многомерного массива в одном формате

У меня есть многомерный массив в следующем формате:

array (
  0 => 
  array (
    'manual' => 1,
    'cancelled' => 1,
    'expired' => 1,
    'earned' => 1,
    'user' => 
    array (
      'user1' => 1,
      'user2' => 1,
      'user3' => 1,
      'user4' => 1,
    ),
    'transfer' => 
    array (
      'transfer1' => 
      array (
        'key1' => 1,
        'key2' => 1,
        'key3' => 1,
      ),
      'transfer2' => 
      array (
        'key5' => 1,
        'key6' => 1,
        'key7' => 1,
      ),
    ),
    'date' => '2018-03-07',
  ),
  1 => 
  array (
    'manual' => 1,
    'cancelled' => 1,
    'expired' => 1,
    'earned' => 1,
    'user' => 
    array (
      'user1' => 1,
      'user2' => 1,
      'user3' => 1,
      'user4' => 1,
    ),
    'transfer' => 
    array (
      'transfer1' => 
      array (
        'key1' => 1,
        'key2' => 1,
        'key3' => 1,
      ),
      'transfer2' => 
      array (
        'key5' => 1,
        'key6' => 1,
        'key7' => 1,
      ),
    ),
    'date' => '2018-03-08',
  ),

) Мне нужно вычислить сумму значений массива с одинаковым индексом. Таким образом, общий массив должен быть следующим

Array
(
    [total] => Array
        (
            [manual] => 2
            [cancelled] => 2
            [expired] => 2
            [earned] => 2
            [user] => Array
                (
                    [user1] => 2
                    [user2] => 2
                    [user3] => 2
                    [user4] => 2
                )

            [transfer] => Array
                (
                    [transfer1] => Array
                        (
                            [key1] => 2
                            [key2] => 2
                            [key3] => 2
                        )

                    [transfer2] => Array
                        (
                            [key5] => 2
                            [key6] => 2
                            [key7] => 2
                        )
        )

То есть общая сумма должна иметь тот же формат, за исключением даты, но она должна отображать общую сумму значения. Как это можно сделать в PHP? Я использовал следующий код

$final = array_shift($input);
foreach ($final as $key => &$value){
  $value += array_sum(array_column($input, $key));
}

unset($value);

var_dump($final);

где $input считается первым массивом, а $final — общим. Я думаю, что это работает только с одиночными индексами.


  • same index.-› какой индекс вы использовали для сравнения? 19.03.2018
  • @AlivetoDie индекс manual в 0-м элементе необходимо добавить к manual в первом элементе. Таким образом, общее значение для индекса manual равно 2. То же самое для всех других индексов. 19.03.2018
  • так что, основываясь на руководстве, вы собираетесь проверить, нужно ли добавлять подмассивы или нет? Я прав? 19.03.2018
  • вы можете найти решение здесь .com/questions/1496682/ 19.03.2018
  • Нет. Это как $total['total']['manual'] = $array[0]['manual']+ $array[1]['manual'] и $total['total']['cancelled'] = $array[0]['cancelled']+ $array[1]['cancelled'] и $total['total']['user']['user1'] = $array[0]['user']['user1']+ $array[1]['user']['user1'] 19.03.2018
  • @kashalo Я использовал приведенный там ответ с наибольшим количеством голосов. Но выдает ошибку. Я думаю, что это будет работать только с массивами без вложенных групп. 19.03.2018
  • используйте код ссылки: - eval.in/974483 и попробуйте и дайте мне знать, сработало или нет? 19.03.2018
  • @AlivetoDie на самом деле нужно добавить значения в эти индексы. Не просто один, а также у меня есть несколько элементов в основном массиве. не 2 19.03.2018
  • it needs to add the values in these indexes. -› я не могу этого понять. Пожалуйста, объясни 19.03.2018
  • @HappyCoder, не могли бы вы ввести данные в форме var_export вместо print_r. Поскольку это на самом деле не тривиальный вопрос, поэтому люди, пытающиеся ответить на ваш вопрос, могут захотеть поиграть с некоторым кодом. И это действительно сложно сделать, когда вы не можете скопировать/вставить ввод. 19.03.2018
  • @sevavietl отредактировал вопрос и добавил результат var_export 19.03.2018
  • @HappyCoder, спасибо 19.03.2018

Ответы:


1

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

Там

Если элемент представляет собой массив, создайте его в массиве результатов и запустите функцию для каждого ключа. Если у него есть номер, просто добавьте значение к результату.

Вот ОБРАЗЕЦ

<?php
// Array with data
$arr=array(array('manual'=>1,'cancelled'=>1,'expired'=>1,'earned'=>1,'user'=>array('user1'=>1,'user2'=>1,'user3'=>1,'user4'=>1,),'transfer'=>array('transfer1'=>array('key1'=>1,'key2'=>1,'key3'=>1,),'transfer2'=>array('key5'=>1,'key6'=>1,'key7'=>1,)),'date'=>'2018-03-07',),array('manual'=>1,'cancelled'=>1,'expired'=>1,'earned'=>1,'user'=>array('user1'=>1,'user2'=>1,'user3'=>1,'user4'=>1,),'transfer'=>array('transfer1'=>array('key1'=>2,'key2'=>2,'key3'=>2,),'transfer2'=>array('key5'=>2,'key6'=>2,'key7'=>2,)),'date'=>'2018-03-08',)); 

//Init result array
$res=array('total'=>array());

foreach ($arr as $key=>$val) {
    //Run it for each element and store result to $res['total']
   countTotal($res['total'],$val);
}

//Show result
print_r($res);


/*
* Count totals for branch of array
* @param $res - reference to branch of result array
* @param $arr - branch of data array
*/
function countTotal(&$res,$arr) {
        foreach ($arr as $key=>$val) {
            if (is_array($val)) {
                //it's array. Create "branch" in $res and run countTotal() to calc total for it
                if (!isset($res[$key])) $res[$key]=array();
                countTotal($res[$key],$val);
            } else if (is_numeric($val)) {
                // it's number. Create "leaf" if need and add value.
                if (!isset($res[$key])) $res[$key]=0;
                $res[$key]+=$val;
            }
        }
}

Как вы видите, используйте ссылку на ветвь массива результатов для накопления итогов

Полученные результаты

    Array
    (
        [total] => Array
            (
                [manual] => 2
                [cancelled] => 2
                [expired] => 2
                [earned] => 2
                [user] => Array
                    (
                        [user1] => 2
                        [user2] => 2
                        [user3] => 2
                        [user4] => 2
                    )

                [transfer] => Array
                    (
                        [transfer1] => Array
                            (
                                [key1] => 3
                                [key2] => 3
                                [key3] => 3
                            )

                        [transfer2] => Array
                            (
                                [key5] => 3
                                [key6] => 3
                                [key7] => 3
                            )

                    )

            )

    )

Во втором "переводе" я использовал "2", поэтому в сумме получается "3"

19.03.2018

2

Вы можете написать рекурсивную функцию следующим образом:

function array_sum_recursive_assoc($array, &$result = [])
{
    $keys = array_keys($array[0] ?? []);

    foreach ($keys as $key) {
        foreach (($column = array_column($array, $key)) as $value) {
            if (is_array($value)) {
                $result[$key] = [];
                array_sum_recursive_assoc($column, $result[$key]);
                continue 2;
            }

            // In this case date safe guard.
            if (!is_numeric($value)) {
                continue;
            }

            $result[$key] = ($result[$key] ?? 0) + $value;
        }
    }

    return $result;
}

var_dump(array_sum_recursive_assoc($array));

Вот демонстрация.

19.03.2018
Новые материалы

Объяснение документов 02: BERT
BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

Учебные заметки: создание моего первого пакета Node.js
Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


Для любых предложений по сайту: [email protected]