使用多个值对数组进行分组,并基于循环和排序数组中的组值对数组求和

问题描述:

我想对数组值进行分组并找到总计(基于值的数组值之和),然后根据总计对数组进行排序.我想按资金类型(私募,创投,其他")和总资金的总和(最终值")对用户进行分组

I want to group array values and find total (sum of array value-based of the group by value) and then sort array based on total. I want to group by users by fund type ("Private, VC, Others") and the sum of total fund ("last value")

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

I have set up a demo link here.

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);

我要在输出下面

分组依据(私有,VC,其他"),因此值格式如[私有总和,VC总和,其他总和]

Group by ("Private, VC, Others") so value format like [sum of the private, sum of VC, a sum of Others ]

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

然后我要基于总和对数组进行排序

And then I want to sort array based on the total sum

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

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

Anyone please suggest possible solution to fic this issue?

谢谢

如果这是数据库查询的结果,则可以肯定可以在该查询中更有效地完成此操作.但是,您可以分3个阶段获得所需的结果:

If this is the result of a database query, this could almost certainly have been done more efficiently in that query. However, you can get the results you want in 3 stages:

  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']);
    });

输出(用于示例数据):

Output (for your sample data):

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:

Note I've left the keys of the inner array as associative as that seems more useful. If you would prefer numeric keys, you would need to sort each internal array so the keys were in the same order, and then take array_values of each entry:

$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上进行演示

要以名称和值在一起的数组形式获取结果,请用以下代码替换最后一段代码:

To get the results in the form of an array with the name and values together, replace the last piece of code with this:

$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]