具有相同用户ID的相同键的总和值也保留在那里的日期作为键

时间:2018-06-27 11:16:39

标签: php multidimensional-array merge sum

我试图将每个totalPlayed的{​​{1}}值相加。我不想更改数组的整体结构,我只想通过对user_id值求和来压缩events子数组。

这是一个示例数组,如json:

totalPlayed

我想要这个结果:

[
  {
    "date": "May 29",
    "date_start": "2018-05-29 05:00:00",
    "date_end": "2018-05-30 04:59:59",
    "interval": 29,
    "calDay": "29 days ago",
    "events": [
      {
        "totalPlayed": 184,
        "user_id": 479
      },
      {
        "totalPlayed": 906,
        "user_id": 479
      },
      {
        "totalPlayed": 400,
        "user_id": 1446
      },
      {
        "totalPlayed": 500,
        "user_id": 1446
      }

    ]
  },
  {
    "date": "May 30",
    "date_start": "2018-05-30 05:00:00",
    "date_end": "2018-05-31 04:59:59",
    "interval": 28,
    "calDay": "28 days ago",
    "events": [
      {
        "totalPlayed": 1469,
        "user_id": 1626
      },
      {
        "totalPlayed": 1482,
        "user_id": 1690
      },
      {
        "totalPlayed": 1434,
        "user_id": 1690
      }
    ]
  }
]

我尝试了以下功能,但不适用于我。

array (
  0 => 
  array (
    'date' => 'May 29',
    'date_start' => '2018-05-29 05:00:00',
    'date_end' => '2018-05-30 04:59:59',
    'interval' => 29,
    'calDay' => '29 days ago',
    'events' => 
    array (
      0 => 
      array (
        'totalPlayed' => 1090,
        'user_id' => 479,
      ),
      1 => 
      array (
        'totalPlayed' => 900,
        'user_id' => 1446,
      ),
    ),
  ),
  1 => 
  array (
    'date' => 'May 30',
    'date_start' => '2018-05-30 05:00:00',
    'date_end' => '2018-05-31 04:59:59',
    'interval' => 28,
    'calDay' => '28 days ago',
    'events' => 
    array (
      0 => 
      array (
        'totalPlayed' => 1469,
        'user_id' => 1626,
      ),
      1 => 
      array (
        'totalPlayed' => 2916,
        'user_id' => 1690,
      ),
    ),
  ),
)

3 个答案:

答案 0 :(得分:1)

假设您的主数组名为$data,此解决方案将使用求和值构建一个新数组,然后您可以用创建的新数组替换原始数组:

function computeOutcome($array) {
    $events = [];
    foreach ($array as $evt) {
        if (in_array($evt['user_id'], array_column($events, 'user_id'))) {
            $key = array_search($evt['user_id'], array_column($events, 'user_id'));
            $events[$key]['totalPlayed'] += $evt['totalPlayed'];
        } else {
            $events[] = $evt;
        }
    }
    return $events;
}

$data['events'] = computeOutcome($data['events']);

编辑:
由于您具有 JSON 字符串,因此我得到的结果与之前相同(假设您的JSON字符串称为$json):

$data = json_decode($json, true);

// Still using the function I wrote before
for ($i = 0; $i < count($data); $i++) {
    $data[$i]['events'] = computeOutcome($data[$i]['events']);
}

// Print result
echo '<pre>' . print_r($data, true) . '</pre>';

文档:

答案 1 :(得分:1)

与迭代的in_array()调用相比,在深层子阵列上使用临时键可以提高性能。有关更多说明,请参见嵌入式注释。

代码:(Demo

function computeOutcome($array) {
    foreach ($array as &$set) {  // modify by reference
        $tmp = [];  // use a fresh temporary array for each date-set
        foreach ($set['events'] as $record) {
            $id = $record['user_id'];
            if (isset($tmp[$id])) {
                $tmp[$id]['totalPlayed'] += $record['totalPlayed'];  // increase the tally
            } else {
                $tmp[$id] = $record;  // store the whole row
            }
        }
        $set['events'] = array_values($tmp);  // remove temporary keys
    }
    return $array;
}

$json = <<<JSON
[
  {
    "date": "May 29",
    "date_start": "2018-05-29 05:00:00",
    "date_end": "2018-05-30 04:59:59",
    "interval": 29,
    "calDay": "29 days ago",
    "events": [
      {
        "totalPlayed": 184,
        "user_id": 479
      },
      {
        "totalPlayed": 906,
        "user_id": 479
      },
      {
        "totalPlayed": 400,
        "user_id": 1446
      },
      {
        "totalPlayed": 500,
        "user_id": 1446
      }

    ]
  },
  {
    "date": "May 30",
    "date_start": "2018-05-30 05:00:00",
    "date_end": "2018-05-31 04:59:59",
    "interval": 28,
    "calDay": "28 days ago",
    "events": [
      {
        "totalPlayed": 1469,
        "user_id": 1626
      },
      {
        "totalPlayed": 1482,
        "user_id": 1690
      },
      {
        "totalPlayed": 1434,
        "user_id": 1690
      }
    ]
  }
]
JSON;

var_export(computeOutcome(json_decode($json, true)));

答案 2 :(得分:0)

您可以使用array_column查找用户ID,使用array_intersect查找相应的值,并使用array_sum求和。

$data =json_decode('
[
{
"date": "May 29",
"date_start": "2018-05-29 05:00:00",
"date_end": "2018-05-30 04:59:59",
"interval": 29,
"calDay": "29 days ago",
"events": [
  {
    "totalPlayed": 184,
    "user_id": 479
  },
  {
    "totalPlayed": 906,
    "user_id": 479
  },
  {
    "totalPlayed": 400,
    "user_id": 1446
  },
  {
    "totalPlayed": 500,
    "user_id": 1446
  }

 ]
},
{
"date": "May 30",
"date_start": "2018-05-30 05:00:00",
"date_end": "2018-05-31 04:59:59",
"interval": 28,
"calDay": "28 days ago",
"events": [
  {
    "totalPlayed": 1469,
    "user_id": 1626
  },
  {
    "totalPlayed": 1482,
    "user_id": 1690
  },
  {
    "totalPlayed": 1434,
    "user_id": 1690
  }
]
}
]', true);
Foreach($data as $key => $arr){
    $userid = array_column($arr["events"], "user_id");
    $played = array_column($arr["events"], "totalPlayed");
    Foreach(array_unique($userid) as $id){
        $temp = array_intersect_key($played, array_intersect($userid, [$id]));
        $new[$key]['events']['date'] = $arr['date'];
        $new[$key]['events'][] = ['total played' => array_sum($temp), 'user_id' => $id];
    }
}
Var_dump($new);

https://3v4l.org/G1jKI

这只会循环唯一的用户ID,而不是整个数组。

将来,您可以将数组发布为Json或var_export,这对我们帮助您将更加容易。