【问题标题】:Group by array using multiple values and sum of array based on group values in loop and sorting array使用多个值按数组分组,并根据循环和排序数组中的组值对数组求和
【发布时间】:2020-02-08 06:15:18
【问题描述】:

我想对数组值进行分组并找到总计(按值分组的基于数组值的总和),然后根据总计对数组进行排序。我想按基金类型(“Private, VC, Others”)和总基金的总和(“last value”)按用户分组

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

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") 所以值格式如 [sum of the private, sum of VC, a sum of Others]

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

有人请提出解决这个问题的可能方法吗?

谢谢

【问题讨论】:

    标签: php arrays sorting multidimensional-array


    【解决方案1】:

    如果这是数据库查询的结果,那么几乎可以肯定在该查询中可以更有效地完成此操作。但是,您可以分 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
            )
    )
    

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

    Demo on 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]
    

    【讨论】:

    • @Rigal 抱歉,我不小心改变了排序。查看我的编辑
    • @Rigal 我刚刚进行了另一次编辑,如果您愿意,可以为内部数组提供数字键
    • 非常感谢您的快速帮助。我想要每个数组的对象。 IE ['Andew',0, 480, 600]。
    • @Rigal 我的输出正是您在问题中所要求的。
    • 是的,但我想将对象转换为显示图表,所以我需要 ['Andew',0, 480, 600],['john',120,0,150],['Walid',0 ,0,160] .您能建议我以相同的对象格式进行转换吗?
    猜你喜欢
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 2013-04-14
    • 1970-01-01
    相关资源
    最近更新 更多