Рекурсивно объединять как индексы

У меня есть массив, который имеет как индексы, которые я пытаюсь объединить вместе. По какой-то причине я не могу обернуть голову вокруг этого.

Оригинальный массив

$seperateArray = json_decode('[
{ "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Harold" },
{ "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Arthur" },
{ "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Tom" },
{ "tier1": "Group2", "tier2": "Blue", "tier3": "Round", "tier4": "Beth" },
{ "tier1": "Group3", "tier2": "Blue", "tier3": "Round", "tier4": "Peter" }]', true);

Превратите это в:

{
    "Group1": {
        "Blue": {
            "Round": [
                "Harold",
                "Arthur",
                "Tom"
            ]
        }
    },
    "Group2": {
        "Blue": {
            "Round": [
                "Peter"
            ]
        }
    }
}

Вот где я сейчас нахожусь, но я не знаю, двигаюсь ли я в правильном направлении.

$newCombined = array();

//this each statement will show every tier 1-4 array object
foreach($seperateArray as $s) {

    if(!array_key_exists($s['tier1'], $newCombined) $newCombined[$s['tier1']] = array();
    if(!array_key_exists($newCombined[$s['tier1']][$s['tier2']], $newCombined[$s['tier1']])) $newCombined[$s['tier1']][$s['tier2']] = array();
    //.. and so on

}

2 ответа

Решение

Если только tier4 может создать массив, тогда это просто зацикливание и присваивание (если вы в порядке с уведомлениями о глушении):

$array = json_decode('...', true);
$new = [];

foreach ($array as $e)
    @$new[$e['tier1']][$e['tier2']][$e['tier3']][] = $e['tier4'];

echo json_encode($new, JSON_PRETTY_PRINT); # to print what you asked for

Чтобы сделать назначение немного менее загадочным:

foreach ($array as $e) {
    list($t1, $t2, $t3, $t4) = array_values($e);
    @$new[$t1][$t2][$t3][] = $t4;
}

Чтобы вернуться из $new к исходному массиву:

$original = [];

foreach (array_keys($new) as $t1)
    foreach (array_keys($new[$t1]) as $t2)
        foreach (array_keys($new[$t1][$t2]) as $t3)
            foreach ($new[$t1][$t2][$t3] as $t4)
                $original[] = [
                    'tier1' => $t1,
                    'tier2' => $t2,
                    'tier3' => $t3,
                    'tier4' => $t4,
                ];

echo json_encode($original, JSON_PRETTY_PRINT);

Ответ Сидилла идеален, но, поскольку я работал над своим собственным решением, я также опубликую его:

$input = json_decode('[
  { "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Harold" },
  { "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Arthur" },
  { "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Tom" },
  { "tier1": "Group2", "tier2": "Blue", "tier3": "Round", "tier4": "Beth" },
  { "tier1": "Group3", "tier2": "Blue", "tier3": "Round", "tier4": "Peter" }]', true);

$output = [];

foreach($input as $row) {
  $recursion = &$output;
  foreach($row as $key => $value) {
    if ($key != 'tier4' && !isset($recursion[$value])) {
      $recursion[$value] = [];
    }
    if ($key == 'tier4') {
      $recursion[] = $value;
    } else {
      $recursion = &$recursion[$value];
    }
  }
}

var_dump($output);

array (3) {["Group1"] => array (1) {["Blue"] => array (1) {["Round"] => array (3) {[0] => string (6) "Гарольд" [1] => string (6) "Arthur" [2] => string (3) "Tom"}}} ["Group2"] => array (1) {["Blue"] => array (1) {["Round"] => array (1) {[0] => string (4) "Beth"}}} ["Group3"] => array (1) {["Blue"] => array (1) {["Round"] => & array (1) {[0] => string (5) "Peter"}}}}

Не особо горжусь этим, но это работает.

Другие вопросы по тегам