I have data like this:
Which can also be seen as this PHP array:
$items = [
['item1' => 'a', 'item2' => 'c', 'item3' => 'h'],
['item1' => 'a', 'item2' => 'c', 'item3' => 'i'],
['item1' => 'a', 'item2' => 'd', 'item3' => 'j'],
['item1' => 'a', 'item2' => 'd', 'item3' => 'k'],
['item1' => 'b', 'item2' => 'e', 'item3' => 'l'],
['item1' => 'b', 'item2' => 'e', 'item3' => 'm'],
['item1' => 'b', 'item2' => 'f', 'item3' => 'n'],
['item1' => 'b', 'item2' => 'g', 'item3' => 'o'],
];
Or even this (multidimensional) list:
a
c
h
i
d
j
k
b
e
l
m
f
n
g
o
How could I loop through this data and create a multidimensional array like
$items = [
[a, [[c, [h, i]], [d, [j, k]]],
[b, [[e, [l, m]], [f, [n]], [g, [o]]]
];
Basically my aim to build the multidimensional html list, but my brain is stuck.
With the multidimensional array I’d be able to do it.
Thanks!
Here’s an attempt to solve it.
It’s a bit more complicated example.
And it’s "too hard coded".
There are some errors in the indexes.
I’m wondering if there’s a cleaner approach.
<?php
$items = [
['item1' => 'a', 'item2' => 'c', 'item3' => 'd2', 'item4' => 'f'],
['item1' => 'a', 'item2' => 'c', 'item3' => 'd2', 'item4' => 'g'],
['item1' => 'a', 'item2' => 'd', 'item3' => 'd3', 'item4' => 'h'],
['item1' => 'a', 'item2' => 'd', 'item3' => 'e', 'item4' => 'i'],
['item1' => 'b', 'item2' => 'c', 'item3' => 'e', 'item4' => 'j'],
['item1' => 'b', 'item2' => 'c', 'item3' => 'e', 'item4' => 'k'],
['item1' => 'b', 'item2' => 'c', 'item3' => 'e', 'item4' => 'l'],
['item1' => 'b', 'item2' => 'c2', 'item3' => 'e', 'item4' => 'm'],
];
$items_new = [];
$item1 = '';
$item2 = '';
$item3 = '';
$item4 = '';
foreach ($items as $item):
$item1_new = $item['item1'];
$item2_new = $item['item2'];
$item3_new = $item['item3'];
$item4_new = $item['item4'];
if($item1 != $item1_new)
{
$items_new[] = [$item1_new, []];
$item1 = $item1_new;
$item2 = '';
}
if($item2 != $item2_new)
{
$items_new[count($items_new) - 1][] = [$item2_new, []];
$item2 = $item2_new;
$item3 = '';
}
if($item3 != $item3_new)
{
$items_new[count($items_new) - 1][count($items_new[1]) - 1][] = [$item3_new, []];
$item3 = $item3_new;
$item4 = '';
}
if($item4 != $item4_new)
{
$items_new[count($items_new) - 1][count($items_new[1]) - 1][count($items_new[2]) - 1][] = [$item4_new, []];
$item4 = $item4_new;
}
endforeach;
foreach($items_new as $items1)
{
if (is_string($items1))
{
echo $items1 . '<br>';
}
elseif (is_array($items1))
{
foreach($items1 as $items2)
{
if (is_string($items2))
{
echo ' - ' . $items2 . '<br>';
}
elseif (is_array($items2))
{
foreach ($items2 as $items3)
{
if (is_string($items3))
{
echo ' --- ' . $items3 . '<br>';
}
elseif (is_array($items3))
{
foreach ($items3 as $items4)
{
if (is_string($items4))
{
echo ' ----- ' . $items4 . '<br>';
}
elseif (is_array($items4))
{
foreach ($items4 as $items5)
{
if (is_string($items5))
{
echo ' ------- ' . $items5 . '<br>';
}
elseif (is_array($items5))
{
foreach ($items5 as $items6)
{
}
}
}
}
}
}
}
}
}
}
}
?>
2
Answers
Solved!
Use references to avoid keeping track of explicit indexes as you push and manage data grouping.
One reference will determine if a new top level row needs to be instantiated and pushed into the result array. Another reference will determine if a unique second level row needs to be instantiated and pushed into its parent.
Code: (Demo)
Output (with some newlines and tabbing to improve readability):