Reputation: 3323
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.
Upvotes: 0
Views: 97
Reputation: 2216
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.
Upvotes: 1
Reputation: 40653
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
Upvotes: 1