Reputation: 812
So i have this array:
$input = array (
1 => array (
'TitleName' => 'Details',
'TitleID' => 1,
1 => array (
'ID' => 1,
'Name' => 'First Name'
),
2 => array (
'ID' => 2,
'Name' => 'Last Name'
),
3 => array (
'ID' => 4,
'Name' => 'City')
),
12 => array (
'TitleName' => 'System',
'TitleID' => 12,
0 => array (
'ID' => 3,
'Name' => 'Cpu'
)
)
);
And i have an Array that tells me how to order the array above:
$order = array
(
1 => array(
0 => 1, // this is the ID in the third dimension
1 => 4,
2 => 2,
),
12 => array (
0 => 3
)
);
So the point is that i will get in my final array :
Array
(
[1] => Array
(
[TitleName] => Details
[TitleID] => 1
[1] => Array
(
[ID] => 1
[Name] => First Name
)
[2] => Array
(
[ID] => 4
[Name] => City
)
[3] => Array
(
[ID] => 2
[Name] => Last Name
)
)
[12] => Array
(
[TitleName] => System
[TitleID] => 12
[0] => Array
(
[ID] => 3
[Name] => Cpu
)
)
)
Also, how can i move items inside the array to different parent?
I've tried this code, but no luck.
usort($array, function ($a, $b) use ($order) {
$pos_a = array_search($a['id'], $order);
$pos_b = array_search($b['id'], $order);
return $pos_a - $pos_b;
});
Any ideas?? Thanks!
Upvotes: 0
Views: 135
Reputation: 37348
Since your id's are unique, it might be easier to just fill two temporary arrays and then iterate over the ordering array to create your desired output.
Here's a possible solution. No need for array_search here.
Having your two goven arrays, we'll first iterate over the input, seperating the common 1st level elements and it's attributes and the children elements.
To distinguish between attributes of first level elements and chiuldren we use is_numeric on the key (since attribute keys are not numeric) and is_array (just to be sure).
// our temporary arrays
$tmpElements = array();
$tmpChildren = array();
// iterate over array
foreach($input as $key => $value) {
$tmpElementAttributes = array(); // init/reset the temporary attributes array
// iterate over children and attributes
foreach ($value as $subKey => $subValue) {
// if the value is an array and the key is numeric, it is a child element
if(is_array($subValue) && is_numeric($subKey)) {
$tmpChildrenKey = $subValue['ID'];
$tmpChildren[$tmpChildrenKey] = $subValue;
}
else { // otherwise it is an attribute
$tmpElementAttributes[$subKey] = $subValue;
}
}
$tmpElements[$key] = $tmpElementAttributes; // add the gathered attributes that define our firstLevel Element
}
So now we have two arrays. One ($tmpElements
) has all the first Level Elements (Details, Systems) and the other one ($tmpChildren
) has all the child Elements (First Name, Last Name, Cpu, City
). For both arrays we took their id's as array key.
Now we iterate over the ordering array, filling in our child elements into the respective first level elements in our $tmpElements
Array accoring to $order
.
foreach($order as $key => $values) {
foreach($values as $orderId) {
$tmpElements[$key][] = $tmpChildren[$orderId];
}
}
Here, $key
from the first array is the array key for our first level element, both in order as in your source/input and as in our $tmpElements
. So we can use it to identify elements in our array.
The $orderId
from the second foreach is the second level children element ID.
So we use it to reach our respective Children Element.
Hence: $tmpElements[$key][] = $tmpChildren[$orderId];
Upvotes: 1