Группировка по массиву с использованием нескольких значений и суммы массива на основе значений группы в l oop и сортировки массива - PullRequest
1 голос
/ 08 февраля 2020

Я хочу сгруппировать значения массива и найти итог (сумма значений массива на основе группы по значению), а затем отсортировать массив на основе итогов. Я хочу сгруппировать пользователей по типу фонда («Частный, V C, Другие») и сумме общего фонда («последнее значение»)

Я установил здесь демонстрационную ссылку.

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

Я хочу ниже вывода

Группировать по ("Private, V C, Others"), поэтому формат значения такой [сумма частного, сумма V C, сумма других]

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

Любой, пожалуйста предложить возможное решение этой проблемы?

Спасибо

1 Ответ

1 голос
/ 08 февраля 2020

Если это результат запроса к базе данных, это почти наверняка можно было бы сделать более эффективно в этом запросе. Тем не менее, вы можете получить желаемые результаты в 3 этапа:

  1. группировать входные данные по человеку и набрать
    $arr = array();
    foreach ($data  as $key => $item) {
        $arr[$item[0]][$item[3]] = ($arr[$item[0]][$item[3]] ?? 0) + $item[4];
    }
заполните пропущенные значения для каждого человека
    foreach (array_unique(array_column($data, 3)) as $type) {
        foreach ($arr as &$person) {
            if (!isset($person[$type])) $person[$type] = 0;
        }
    }
Сортировка массива
    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
        )
)

Демонстрация на 3v4l.org

Примечание: я оставил ключи внутреннего массива как ассоциативные, так как это кажется более полезным. Если вы предпочитаете цифровые ключи c, вам необходимо отсортировать каждый внутренний массив так, чтобы ключи были в том же порядке, а затем взять 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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...