Получить сумму объектов с одинаковым идентификатором внутри вложенного массива php

Это мой массив объектов на php:

Array( [0]=>
  Array (
    [added_time] => 2018-12-09 14:00:00+00 
    [id] => 123
    [places] => 
      [{
        "place_id" : 1,
        "total" : 5, 
        "empty" : 0,
        "weight" : 68000,
        "persons" : 
         [{
           "person_id" : 2,
           "person_name" : "ABC",
           "total":100
          }, 
          {
           "person_id" : 3
           "person_name" : "DEF",
           "total":200
         }]
      },
        "place_id" : 4,
        "total" : 10, 
        "empty" : 0,
        "weight" : 54000,
        "persons" : 
          [{
            "person_id" : 2,
            "person_name" : "ABC"
            "total":100
           }, 
           {
            "person_id" : 6
            "person_name" : "GHI",
           }
         ]
     ],
  ),
   Array (
    [added_time] => 2018-12-09 15:00:00+00 
    [id] => 456
    [places] => 
      [{
        "place_id" : 1,
        "total" : 5, 
        "empty" : 0,
        "weight" : 68000,
        "persons" : 
         [{
           "person_id" : 2,
           "person_name" : "ABC",
           "total":200
          }, 
          {
           "person_id" : 3
           "person_name" : "DEF",
           "total":300
         }]
      }]
   )
)

Я пытаюсь получить сумму на основе person_id, как группа по person_id.

Мой желаемый результат должен быть:

Array (
 [added_time] => 2018-12-09 14:00:00+00 
 [id] => 123
 persons:array(
   Array([0]=>
     [person_id] : 2,
     [person_name] : "ABC",
     [total]:200
   ),
   Array([1]=>
     [person_id] : 3,
     [person_name] : "DEF",
     [total]:300
   ),
   Array([2]=>
     [person_id] : 6,
     [person_name] : "GHI",
     [total]:500
    )
  ),
 [added_time] => 2018-12-09 15:00:00+00 
 [id] => 123
 persons:array(
   Array([0]=>
     [person_id] : 2,
     [person_name] : "ABC",
     [total]:200
   ),
   Array([1]=>
     [person_id] : 3,
     [person_name] : "DEF",
     [total]:300
    )
  )
)

Как мне добиться такого результата. Я могу использовать foreach, но не хочу его использовать из-за трех итераций.

Есть ли другой способ добиться этого на php и без проблем с производительностью?

покажите нам, что вы пробовали до сих пор и почему это не работает должным образом?

lovelace 10.12.2018 10:23

В вашем вопросе непонятно, чем вы хотите заниматься?

Nasser Ali Karimi 10.12.2018 10:26

Рассмотрите возможность использования рекурсивной функции.

Nikola Petkanski 10.12.2018 12:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
3
240
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете получить это, используя функцию PHP как слияние массивов, столбец-массив, уменьшение массива.

Позвольте разделить это на 3 шага:

1. Общая сумма для всех лиц, указанных в списке лиц. Определите следующую функцию сокращения:

function reduce($carry, $item)
{
    if (!in_array($item["person_name"], array_column($carry, "person_name")))
        $carry[] = $item;
    else {
        foreach($carry as &$person) {
                if ($item["person_name"] == $person["person_name"])
                        $person["total"] += $item["total"];
        }
    }
    return $carry;
}

2. Для каждого элемента в вашем массиве создайте вывод, используя reduce из шага 1:

function reduceElement($arr) {
        $res = array("added_time" => $arr["time"], "id" => $arr["id"]);
        $persons = array();
        foreach($arr["places"] as $place) {
                $persons = array_merge($persons, $place["persons"]);
        }
        $res["persons"] = array_reduce($persons, "reduce", array());
        return $res;
}

3.Скомбинируйте все это:

$elemA= array("id"=>1, "time"=>"2018", "places" => array(array("persons" => array(array("person_name" => "ABC", "total" => 100), array("person_name" => "DEF", "total" => 200))), array("persons" => array(array("person_name" => "ABC", "total" => 100), array("person_name" => "GHI", "total" => 100)))));
$elemB = array("id"=>2, "time"=>"2017", "places" => array(array("persons" => array(array("person_name" => "ABC", "total" => 200), array("person_name" => "DEF", "total" => 300)))));
$arr = array($elemA, $elemB);
$res = array();
foreach($arr as $obj)
    $res[] = reduceElement($obj);

print_r($res);

Это даст вам требуемый выход

Другие вопросы по теме