Recursively merge similar indexes

I have an array that has indexes that I am trying to combine together. For some reason, I cannot circle my head.

Original array

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

Turn it on:

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

That's where I am, but I don’t know if I am moving in the right direction.

$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
source share
2 answers

If only it tier4can create an array, then this is a simple question for looping and assignment (if you are ok with silence notifications):

$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

To make the assignment a little less cryptic:

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

To return from $newto the original array:

$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);
+2
source

Sidyll's answer is perfect, but since I was working on my own solution, I will post it too:

$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] = > (6) "" [2] = > (3) "" }}} [ "Group2" ] = > (1) {[ "" ] = > array (1) {[ "Round" ] = > array (1) {[0] = > string (4) "Beth" }}} [ "Group3" ] = > array (1) {[ "Blue" ] = > array (1) {[ "Round" ] = > & array (1) {[0] = > string (5) "Peter" }}}}

, .

+1

All Articles