首页 > 解决方案 > 使用多个值按数组分组,并根据循环和排序数组中的组值对数组求和

问题描述

我想对数组值进行分组并找到总计(按值分组的基于数组值的总和),然后根据总计对数组进行排序。我想按基金类型(“私人、风险投资、其他”)和总基金的总和(“最后价值”)按用户分组

我在这里设置了一个演示链接。

https://3v4l.org/6WNKE

<?php

$data = [
  [
    'Jon',
    'NO',
    "",
    "Private",
    120
  ],
  [
    'Andew',
    'NO',
    "",
    "VC",
    150
  ],
  [
    'Walid',
    'YES',
    "",
    "Other",
    160
  ],

  [
    'Andew',
    'YES',
    "",
    "VC",
    150
  ],
  [
    'Andew',
    'YES',
    "",
    "VC",
    180
  ],

  [
    'Jon',
    'NO',
    "",
    "Other",
    150
  ],

  [
    'Andew',
    'YES',
    "",
    "Other",
    600
  ]
];

$arr = array();
foreach ($data  as $key => $item) {
      $arr[$item[0]][$key] =   $item['4'];
}

var_dump($arr);

我想要下面的输出

Group by ("Private, VC, Others") 所以值格式像 [私有的总和, VC 的总和, 其他的总和]

Array
(
    [Jon] => [120,110,0]
    [Andew] => [0,480,600]
    [Walid] => [0,0,160]
)

然后我想根据总和对数组进行排序

Array
(
 [Andew] => [0,480,600]
 [Jon] => [120,110,0]
 [Walid] => [0,0,160]
)

任何人请提出可能的解决方案来解决这个问题?

谢谢

标签: phparrayssortingmultidimensional-array

解决方案


如果这是数据库查询的结果,那么几乎可以肯定在该查询中可以更有效地完成此操作。但是,您可以分 3 个阶段获得您想要的结果:

  1. 按人员和类型对输入数据进行分组
    $arr = array();
    foreach ($data  as $key => $item) {
        $arr[$item[0]][$item[3]] = ($arr[$item[0]][$item[3]] ?? 0) + $item[4];
    }
  1. 填写每个人的缺失值
    foreach (array_unique(array_column($data, 3)) as $type) {
        foreach ($arr as &$person) {
            if (!isset($person[$type])) $person[$type] = 0;
        }
    }
  1. 对数组进行排序
    uasort($arr, function ($a, $b) {
        return $b['Private'] + $b['Other'] + $b['VC'] - ($a['Private'] + $a['Other'] + $a['VC']);
    });

输出(用于您的样本数据):

Array
(
    [Andew] => Array
        (
            [VC] => 480
            [Other] => 600
            [Private] => 0
        )
    [Jon] => Array
        (
            [Private] => 120
            [Other] => 150
            [VC] => 0
        )
    [Walid] => Array
        (
            [Other] => 160
            [Private] => 0
            [VC] => 0
        )
)

演示 on3v4l.org

请注意,我将内部数组的键保留为关联的,因为这似乎更有用。如果您更喜欢数字键,则需要对每个内部数组进行排序,使键的顺序相同,然后取出array_values每个条目:

$key_rank = array('Private' => 0, 'VC' => 1, 'Other' => 2);
foreach ($arr as &$person) {
    uksort($person, function ($a, $b) use ($key_rank) {
        return $key_rank[$a] - $key_rank[$b];
    });
    $person = array_values($person);
}

输出:

Array
(
    [Andew] => Array
        (
            [0] => 0
            [1] => 480
            [2] => 600
        )    
    [Jon] => Array
        (
            [0] => 120
            [1] => 0
            [2] => 150
        )    
    [Walid] => Array
        (
            [0] => 0
            [1] => 0
            [2] => 160
        )    
)

3v4l.org 上的演示

要以包含名称和值的数组形式获取结果,请将最后一段代码替换为:

$key_rank = array('Private' => 0, 'VC' => 1, 'Other' => 2);
$result = array();
foreach ($arr as $name => &$person) {
    uksort($person, function ($a, $b) use ($key_rank) {
        return $key_rank[$a] - $key_rank[$b];
    });
    $result[] = array_merge(array($name), array_values($person));
}

print_r($result);

输出:

Array
(
    [0] => Array
        (
            [0] => Andew
            [1] => 0
            [2] => 480
            [3] => 600
        )
    [1] => Array
        (
            [0] => Jon
            [1] => 120
            [2] => 0
            [3] => 150
        )
    [2] => Array
        (
            [0] => Walid
            [1] => 0
            [2] => 0
            [3] => 160
        )
)

[Demo on 3v4l.org][3]

推荐阅读