0

My array contains the following:

Array ( [0] => Events - Central [1] => Central [2] => Finance [3] => 17 [5] => 11 [8] => 11  )
Array ( [0] => Events - Central [1] => Central [2] => HR [3] => 17 [5] => 11 [8] => 11 )
Array ( [0] => Events - Central [1] => Central [2] => IT [3] => 17 [5] => 11 [8] => 11  )
Array ( [0] => Events - Central [1] => London [2] => Sales [3] => 17 [5] => 11 [8] => 11  )
Array ( [0] => Events - Central [1] => London [2] => Marketing [3] => 17 [5] => 11 [8] => 11 )
Array ( [0] => Events - Central [1] => London [2] => HR [3] => 17 [5] => 11 [8] => 11  )
Array ( [0] => Piloting [1] => London [2] => HR [3] => 17 [5] => 11 [8] => 11  )
Array ( [0] => Piloting [1] => London [2] => IT [3] => 17 [5] => 11 [8] => 11  )

Now, using a simple WHILE loop allows me to loop through the array and I can easily extract the information I need but I'm struggling because I need to bring back distinct values (and I cannot change the SQL code).

The output would be a simple table like this, but notice that level 1 and 2 of the table are not repeated:

Events - Central          17
    Central               17
        Finance           11
        HR                 1
        IT                 1
    London                28
        Sales             17
        Marketing          2
        HR                 5
Piloting                  37
    London                37
       HR                 30
       IT                  7

In short, I'm trying to bring back distinct instances - if that makes sense?

Is this even possible without deconstructing the array?

I'm very concious that I may not have illustrated/ framed this question well.

9
  • So array positions 0,1 and 2 have the "headings" but where do the numbers come from. I see they're in the rest of the array "somewhere" but I can't see any clear logic behind them. Commented Oct 30, 2017 at 14:30
  • 1
    Can You Please Give me a simple array with these values ? Commented Oct 30, 2017 at 14:31
  • Apols - I can see it's not clear. It's positions 3, 5 and 8 - note that the numbers I reference in the table example won't match the Array - they are both for example purposes. Commented Oct 30, 2017 at 14:31
  • 1
    What fields are supposed to be unique? Commented Oct 30, 2017 at 14:32
  • 1
    If you don't provide example output that matches the example input, we're probably not going to be able to help. Commented Oct 30, 2017 at 14:32

2 Answers 2

1

Here's what you can do to (a) echo the data you need and (b) create an array with said data vaguely arranged in a way you can work with:

<?php
$superArray = [
    [ "Events - Central", "Central", "Finance",   17, 0, 11, 0, 0, 11, 0 ],
    [ "Events - Central", "Central", "HR",        17, 0, 11, 0, 0, 11, 0 ],
    [ "Events - Central", "Central", "IT",        17, 0, 11, 0, 0, 11, 0 ],
    [ "Events - Central", "London",  "Sales",     17, 0, 11, 0, 0, 11, 0 ], 
    [ "Events - Central", "London",  "Marketing", 17, 0, 11, 0, 0, 11, 0 ],
    [ "Events - Central", "London",  "HR",        17, 0, 11, 0, 0, 11, 0 ],
    [ "Piloting",         "London",  "HR",        17, 0, 11, 0, 0, 11, 0  ],
    [ "Piloting",         "London",  "IT",        17, 0, 11, 0, 0, 11, 0 ]
];



usort($superArray, function ($a,$b) {
    return $a[0] == $b[0] && $a[1]==$b[1]
        ? $a[2]<=>$b[2]
        : (
            $a[0] == $b[0]
            ?$a[1]<=>$b[1]
            :$a[0]<=>$b[0]
        );
});

$lastSeen = [];
$buildArray = [];

foreach ($superArray as $array) {

    if (!isset($lastSeen[0]) || $lastSeen[0] != $array[0]) {
        $lastSeen[0] = $array[0];
        $lastSeen[1] = null;
        echo $array[0]."\t".$array[3].PHP_EOL;
        $buildArray[]= [
            "level" => 0,
            "name" => $array[0],
            "value" => $array[3]
        ];
    }
    if (!isset($lastSeen[1]) || $lastSeen[1] != $array[1]) {
        $lastSeen[1] = $array[1];
        $lastSeen[2] = null;
        echo "\t".$array[1]."\t".$array[5].PHP_EOL;
        $buildArray[]= [
            "level" => 1,
            "name" => $array[1],
            "value" => $array[5]
        ];

    }
    if (!isset($lastSeen[2]) || $lastSeen[2] != $array[2]) {
        $lastSeen[2] = $array[2];
        echo "\t\t".$array[2]."\t".$array[8].PHP_EOL;
        $buildArray[]= [
            "level" => 2,
            "name" => $array[2],
            "value" => $array[8]
        ];

    }

}


print_r($buildArray);

This will print:

Events - Central    17
    Central 11
        Finance 11
        HR  11
        IT  11
    London  11
        HR  11
        Marketing   11
        Sales   11
Piloting    17
    London  11
        HR  11
        IT  11

The array structure will be:

Array
(
    [0] => Array
        (
            [level] => 0
            [name] => Events - Central
            [value] => 17
        )

    [1] => Array
        (
            [level] => 1
            [name] => Central
            [value] => 11
        )

    [2] => Array
        (
            [level] => 2
            [name] => Finance
            [value] => 11
        )

    [3] => Array
        (
            [level] => 2
            [name] => HR
            [value] => 11
        )

    [4] => Array
        (
            [level] => 2
            [name] => IT
            [value] => 11
        )

    [5] => Array
        (
            [level] => 1
            [name] => London
            [value] => 11
        )

    [6] => Array
        (
            [level] => 2
            [name] => HR
            [value] => 11
        )

    [7] => Array
        (
            [level] => 2
            [name] => Marketing
            [value] => 11
        )

    [8] => Array
        (
            [level] => 2
            [name] => Sales
            [value] => 11
        )

    [9] => Array
        (
            [level] => 0
            [name] => Piloting
            [value] => 17
        )

    [10] => Array
        (
            [level] => 1
            [name] => London
            [value] => 11
        )

    [11] => Array
        (
            [level] => 2
            [name] => HR
            [value] => 11
        )

    [12] => Array
        (
            [level] => 2
            [name] => IT
            [value] => 11
        )

)

The idea is to first put all arrays in a combined array and then sort according to the priorities (I think they're already sorted though). Having done that you keep track on what you've seen for each level and re-construct an array based on that.

Keep in mind this is very hard-coded stuff but you could probably generalize it if you need to.

Example at: http://sandbox.onlinephpfunctions.com/code/bf92828a5561d59d503e5765cc6b566a5acc0532

Sign up to request clarification or add additional context in comments.

1 Comment

Incredibly helpful - thank you. I think, without being able to change the query, I'm looking at deconstructing the array and/ hard coding as you say. However, the above really helps. Thanks and appreciated.
1

A slightly different take on apokryfos's answer, but a similar concept. The idea is to use the de-duping ability of array keys in PHP to build up the hierarchical array:

$data = [];
$data[] = [0 => 'Events - Central', 1 => 'Central', 2 => 'Finance', 3 => 17, 5 => 11, 8 => 11];
$data[] = [0 => 'Events - Central', 1 => 'Central', 2 => 'HR', 3 => 17, 5 => 11, 8 => 11];
$data[] = [0 => 'Events - Central', 1 => 'Central', 2 => 'IT', 3 => 17, 5 => 11, 8 => 11];
$data[] = [0 => 'Events - Central', 1 => 'London', 2 => 'Sales', 3 => 17, 5 => 11, 8 => 11];
$data[] = [0 => 'Events - Central', 1 => 'London', 2 => 'Marketing', 3 => 17, 5 => 11, 8 => 11];
$data[] = [0 => 'Events - Central', 1 => 'London', 2 => 'HR', 3 => 17, 5 => 11, 8 => 11];
$data[] = [0 => 'Piloting', 1 => 'London', 2 => 'HR', 3 => 17, 5 => 11, 8 => 11];
$data[] = [0 => 'Piloting', 1 => 'London', 2 => 'IT', 3 => 17, 5 => 11, 8 => 11];

$tree_root = [];

// map the keys in the $data array to each other
$caption_to_value_mapping = [
    0 => 3,
    1 => 5,
    2 => 8
];

foreach ($data as $datum) {
    $sub_tree = &$tree_root;
    foreach ($caption_to_value_mapping as $level_index => $value) {
        $caption = $datum[$level_index];
        if (!isset($sub_tree[$caption])) {
            $sub_tree[$caption] = ['next_level' => []];
        }
        $sub_tree[$caption]['caption'] = $caption;
        $sub_tree[$caption]['value'] = $datum[$value];
        $sub_tree = &$sub_tree[$caption]['next_level'];
    }
}

var_dump($tree_root);

You can then use $tree_root in a recursive function to build the display of the data.

Note that this is generic and will take any number of levels, as long as the $caption_to_value_mapping is maintained.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.