I need to group values in my flat array so that each non-integer value starts a new group/row in my result array and every integer value encountered until the next occurring non-integer should be pushed into a subarray in the respective group/row.
Input:
$unitsList = [
"Aulas Gratuitas",
"149",
"151",
"153",
"Módulo 0",
"964",
"989",
"Módulo 1",
"985",
"1079",
"1001",
"1003"
"Módulo 2",
"1009"
];
Current code:
$newArr = array();
foreach( $unitsList as $item ) {
if( !is_numeric($item) ) {
$title = array( "title" => $item, "units" => "" );
array_push( $newArr, $title);
} elseif ( is_numeric($item) ) {
$number = $item;
array_push( $newArr, $number);
}
}
Current result:
[
[
"title" => "Aulas Gratuitas",
"units" => ""
]
"149",
"151",
"153",
[
"title" => "Módulo 0",
"units" => ""
],
"964",
"989",
[
"title" => 'Módulo 1',
"units" => ""
],
"985",
"1079",
"1001",
"1003"
[
"title" => 'Módulo 2',
"units" => ''
],
"1009"
]
As you can see, I am having a hard time adding the numbers into the "units" key.
Desired result:
[
[
"title" => "Aulas Gratuitas",
"units" => ["149", "151", "153"]
],
[
"title" => 'Módulo 0',
"units" => ["964", "989"]
],
[
"title" => 'Módulo 1',
"units" => ["985", "1079", "1001", "1003"]
],
[
"title" => "Módulo 2",
"units" => ["1009"]
]
]
3
Answers
Note that your numbers after the title CANNOT be strings, otherwise this function will recognize it as new titles.
This code will output:
Items in the given list aren’t regular. The first item has three units, and the second has two units. We cannot convert them into the expected structure without controlling the type of each item. My solution is below. I added explanations as a comment line.
So that you don’t need to keep track of first level indexes, use a reference variable and push related data into that AFTER pushing the new row into the result array.
Code: (Demo)
unset()
is used to destroy the reference to the previous group, otherwise newly pushed data would be sent to two (or more) places in the result array.Reference variables have a default value of
null
. If yourtitle
values are guaranteed to be followed by an integer/unit value, then$units = [];
can be removed. If you have atitle
and then anothertitle
there will be no data for the formertitle
group. With the explicit array declaration, the group will have an emptyunits
array instead ofnull
.Related questions answered with the same general technique:
If you are running PHP7.3 or higher (and by this point you definitely should be) AND you are intimidated/mystified by using a reference variable, then you can leverage
array_key_last()
to locate the latest created array row.Code: (Demo)