How can I turn this flat array into a multi-dimensional array according to the matched key?
$items = [
0 => [
'id' => 100,
'parent' => 0,
'url' => 'Home'
],
1 => [
'id' => 101,
'parent' => 0,
'url' => 'About'
],
2 => [
'id' => 102,
'parent' => 101,
'url' => 'Group'
],
3 => [
'id' => 103,
'parent' => 102,
'url' => 'Mission'
],
4 => [
'id' => 104,
'parent' => 102,
'url' => 'Vision'
],
];
My attempt:
$new_items = array();
foreach ($items as $key => $item) {
// Store what you need.
$temp_item = array(
'id' => $item['id'],
'url' => $item['url'],
'parent_id' => $item['parent'],
'children' => array()
);
// Item does not have a parent so item_parent equals 0 (false).
if (!$item['parent']) {
// Push the item to the array.
array_push($new_items, $temp_item);
}
// Item that has a parent.
if ($item['parent']) {
// Search key by column 'id'.
$key = array_search($item['parent'], array_column($new_items, 'id'));
// Push sub item to the children array.
array_push($new_items[$key]['children'], $temp_item);
}
}
print_r($new_items);
Result:
Array
(
[0] => Array
(
[id] => 100
[url] => Home
[parent_id] => 0
[children] => Array
(
[0] => Array
(
[id] => 103
[url] => Mission
[parent_id] => 102
[children] => Array
(
)
)
[1] => Array
(
[id] => 104
[url] => Vision
[parent_id] => 102
[children] => Array
(
)
)
)
)
[1] => Array
(
[id] => 101
[url] => About
[parent_id] => 0
[children] => Array
(
[0] => Array
(
[id] => 102
[url] => Group
[parent_id] => 101
[children] => Array
(
)
)
)
)
)
This is what I am after:
Array
(
[0] => Array
(
[id] => 100
[url] => Home
[parent_id] => 0
[children] => Array
(
)
)
[1] => Array
(
[id] => 101
[url] => About
[parent_id] => 0
[children] => Array
(
[0] => Array
(
[id] => 102
[url] => Group
[parent_id] => 101
[children] => Array
(
[0] => Array
(
[id] => 103
[url] => Mission
[parent_id] => 102
[children] => Array
(
)
)
[1] => Array
(
[id] => 104
[url] => Vision
[parent_id] => 102
[children] => Array
(
)
)
)
)
)
)
)
Any ideas and suggestions?
From link
I have changed function parameters as per requirement.
Here is your code.
function buildTree(array $elements, $options = [
'parent_id_column_name' => 'parent',
'children_key_name' => 'children',
'id_column_name' => 'id'], $parentId = 0)
{
$branch = array();
foreach ($elements as $element) {
if ($element[$options['parent_id_column_name']] == $parentId) {
$children = buildTree($elements, $options, $element[$options['id_column_name']]);
if ($children) {
$element[$options['children_key_name']] = $children;
}else{
$element[$options['children_key_name']] = []; // added this line for empty children array
}
$branch[] = $element;
}
}
return $branch;
}
Here is your working demo.
Related
I need help. I have an array of items like this one:
[7646] => Array
(
[0] => Array
(
[id] => 156153
[tmplvarid] => 5
[value] => 2
)
[1] => Array
(
[id] => 56795
[tmplvarid] => 7
[value] => 430
)
[2] => Array
(
[id] => 56798
[tmplvarid] => 19
[value] => rate_08
)
),
[7647] => Array ()
And I need to change array indexes to value of property tmplvarid in sub array to transform array like this:
`[7646] => Array
(
[5] => Array
(
[id] => 156153
[tmplvarid] => 5
[value] => 2
)
[7] => Array
(
[id] => 56795
[tmplvarid] => 7
[value] => 430
)
[19] => Array
(
[id] => 56798
[tmplvarid] => 19
[value] => rate_08
)
)
How can I transform it in assosiative array ?
set index value from array value using foreach loop
Code
<?PHP
$arr = [
"7646" => array
(
[
"id"=> 156153,
"tmplvarid" => 5,
"value" => 2
],
[
"id"=> 56795,
"tmplvarid" => 7,
"value" => 430
],
[
"id"=> 56798,
"tmplvarid" => 19,
"value" => "rate_08"
]
)
];
echo "<pre>";
print_r($arr);
$newarr= [];
foreach($arr as $key => $value)
{
foreach($value as $key1 => $value1)
{
$newarr[$key][$value1['tmplvarid']] = $value1;
}
}
print_r($newarr);
?>
Output
Array
(
[7646] => Array(
[5] => Array
(
[id] => 156153
[tmplvarid] => 5
[value] => 2
)
[7] => Array
(
[id] => 56795
[tmplvarid] => 7
[value] => 430
)
[19] => Array
(
[id] => 56798
[tmplvarid] => 19
[value] => rate_08
)
)
)
I have an array that looked like this
Array
(
[child-safety-lock] => Array
(
[0] => Array
(
[id] => 652
[name] => CHILD LOCK (YES/NO)
)
[1] => Array
(
[id] => 336
[name] => CHILD LOCK (YES/NO)
)
[2] => Array
(
[id] => 19
[name] => Child Lock
)
[3] => Array
(
[id] => 398
[name] => CHILD LOCK (YES/NO)
)
[4] => Array
(
[id] => 155
[name] => CHILD SAFETY LOCK
)
[5] => Array
(
[id] => 329
[name] => CHILD LOCK
)
[6] => Array
(
[id] => 96
[name] => CHILD LOCK
)
[7] => Array
(
[id] => 184
[name] => CHILD SAFETY LOCK
)
[8] => Array
(
[id] => 875
[name] => CHILD SAFETY LOCK (YES/NO)
)
[9] => Array
(
[id] => 450
[name] => CHILD LOCK (YES/NO)
)
[10] => Array
(
[id] => 149
[name] => CHILD SAFE LOCK
)
[11] => Array
(
[id] => 374
[name] => CHILD LOCK (YES/NO)
)
[12] => Array
(
[id] => 491
[name] => CHILD LOCK (YES/NO)
)
[13] => Array
(
[id] => 622
[name] => CHILD LOCK (YES/NO)
)
[14] => Array
(
[id] => 1309
[name] => CHILD LOCK (YES/NO)
)
[15] => Array
(
[id] => 1336
[name] => CHILD LOCK (YES/NO)
)
[16] => Array
(
[id] => 1466
[name] => CHILD LOCK (YES/NO)
)
[17] => Array
(
[id] => 1577
[name] => CHILD SAFETY LOCK (YES/NO)
)
[18] => Array
(
[id] => 1715
[name] => CHILD SAFETY LOCK (YES/NO)
)
[19] => Array
(
[id] => 1908
[name] => CHILD LOCK (YES/NO)
)
)
[controls] => Array
(
[id] => 84
[name] => CONTROLS (E.G. TOUCH, DIAL )
)
[turntable-mm] => Array
(
[id] => 77
[name] => TURNTABLE SIZE (MM)
)
[display-type] => Array
(
[id] => 78
[name] => DISPLAY (E.G. LED, LCD, TFT ETC)
)
[smart-inverter-technology] => Array
(
[id] => 83
[name] => SMART INVERTER TECHNOLOGY
)
[power-w] => Array
(
[id] => 80
[name] => POWER LEVEL (W)
)
[capacity-l] => Array
(
[id] => 79
[name] => CAPACITY (L)
)
[steam] => Array
(
[id] => 86
[name] => STEAM FUNCTION
)
[grill-function] => Array
(
[id] => 89
[name] => GRILL FUNCTION
)
[sensor-cook] => Array
(
[id] => 91
[name] => SENSOR COOK
)
[quick-start] => Array
(
[id] => 92
[name] => QUICK START
)
[defrost-function] => Array
(
[id] => 93
[name] => DEFROST
)
[keep-warm-function] => Array
(
[id] => 97
[name] => KEEP WARM
)
[time-remaining-display] => Array
(
[id] => 98
[name] => TIME REMAINING DISPLAY
)
[reheat-function] => Array
(
[id] => 95
[name] => REHEAT
)
[optional-trim-kit] => Array
(
[id] => 99
[name] => TRIM KIT
)
)
How can I return the key 'child-safety-lock' for example if I enter 652 or 336? Another example is returning array key 'controls' if I enter id '84'? I tried using array_filter() for this but i can't make it work, Is there someone might point me in the right direction?
Also have this function but this is not working
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict)!==FALSE)) {
return key($haystack);
}
}
return false;
}
The following should work -
// Reconstruct array to simplify
$temp = [];
foreach ($arr as $key => $val) {
$temp[$key] = $val[0];
}
// extract key & required values to a temporary array
$temp = array_combine(array_keys($temp), array_column($temp, 'id'));
// look for the values and extract the key
$key = array_search(84, $temp);
References -
https://www.php.net/manual/en/function.array-search.php
https://www.php.net/manual/en/function.array-combine.php
https://www.php.net/manual/en/function.array-column.php
Create separate arrays and access it via index:
$data = [
'child-safety-lock' => [
['id' => 652, 'name' => 'CHILD LOCK (YES/NO)'],
['id' => 336, 'name' => 'CHILD LOCK (YES/NO)'],
['id' => 19, 'name' => 'Child Lock'],
],
'controls' => [
'id' => 84, 'name' => 'CONTROLS (E.G. TOUCH, DIAL )'
]
];
$childSafetyLock = array_column($data['child-safety-lock'], 'name', 'id');
$controls = array_column([$data['controls']], 'name', 'id');
var_dump(
$childSafetyLock[652],
$childSafetyLock[336],
$controls[84],
);
or more universal solution:
$data = [
'child-safety-lock' => [
['id' => 652, 'name' => 'CHILD LOCK (YES/NO)'],
['id' => 336, 'name' => 'CHILD LOCK (YES/NO)'],
['id' => 19, 'name' => 'Child Lock'],
],
'controls' => [
'id' => 84, 'name' => 'CONTROLS (E.G. TOUCH, DIAL )'
]
];
$preparedData = [];
foreach ($data as $key => $value) {
$preparedData[$key] = (count($value) === count($value, COUNT_RECURSIVE))
? [$value]
: $value;
}
$groupedData = [];
foreach ($preparedData as $key => $value) {
$groupedData[$key] = array_column($value, 'name', 'id');
}
var_dump(
$groupedData['child-safety-lock'][652],
$groupedData['child-safety-lock'][336],
$groupedData['controls'][84],
);
If you only have one key that has multiple sub array items, and all those ids are unique, you could just map ids to keys:
<?php
$data =
[
'biscuits' => [
[
'id' => 3,
'name' => 'Digestive'
],
[
'id' => 4,
'name' => 'Rich tea'
]
],
'cake' =>
[
'id' => 5,
'name' => 'Victoria'
]
];
foreach($data as $k => $item) {
if($k == 'biscuits') {
foreach($item as $biscuit) {
$id_key[$biscuit['id']] = $k;
}
}
else {
$id_key[$item['id']] = $k;
}
}
var_export($id_key);
Output:
array (
3 => 'biscuits',
4 => 'biscuits',
5 => 'cake',
)
I have a below array:
[product] => Array
(
[0] => Array
(
[qty] => 1
[code] => 147818
[price] => 11
[name] => Product1
)
[1] => Array
(
[qty] => 2
[code] => 147818
[price] => 11
[name] => Product1
)
[2] => Array
(
[qty] => 1
[code] => 567432
[price] => 31
[name] => Product2
)
)
I want to add quantities if the code is same. That is, I want the resulting array to be:
[product] => Array
(
[0] => Array
(
[qty] => 3
[code] => 147818
[price] => 11
[name] => Product1
)
[1] => Array
(
[qty] => 1
[code] => 567432
[price] => 31
[name] => Product2
)
)
It should merge the elements only if the code is same. How can I achieve this?
Try this code, it merge and sum the qty by code
$products = [
[
'qty' => 1,
'code' => 147818,
'price' => 11,
'name' => 'Product1'
],
[
'qty' => 2,
'code' => 147818,
'price' => 11,
'name' => 'Product1'
],
[
'qty' => 1,
'code' => 567432,
'price' => 31,
'name' => 'Product2'
],
];
$output = [];
for ($i=0; $i<count($products); $i++) {
if ($output[$products[$i]['code']]['code'] == $products[$i]['code']) {
$output[$products[$i]['code']]['qty'] += $products[$i]['qty'];
}else{
$output[$products[$i]['code']] = $products[$i];
}
}
$output = array_values($output);
print_r($output);
Here is input array with an n-level depth
array
(
[0] => array
(
[id] => 1
[parent_id] => 0
[variable_name] => menus
[variable_value] =>
[children] => array
(
[0] => array
(
[id] => 2
[parent_id] => 1
[variable_name] => products
[variable_value] => {"name":"Products", "link":"cctv.html", "show":"1"},
)
[1] => array
(
[id] => 3
[parent_id] => 1
[variable_name] => companies
[variable_value] => {"name":"Companies", "link":"companies.html", "show":"1"},
),
),
)
[1] => array
(
[id] => 4
[parent_id] => 0
[variable_name] => breadcrumbs
[variable_value] =>
[children] => array
(
[0] => array
(
[id] => 5
[parent_id] => 4,
)
[1] => array
(
[id] => 6
[parent_id] => 4
[variable_name] => companies
[variable_value] => {"name":"Companies", "link":"companies.html", "show":"1"},
),
),
)
[2] => array
(
[id] => 7
[parent_id] => 0
[variable_name] => products
[variable_value] =>
[children] => array
(
[0] => array
(
[id] => 8
[parent_id] => 7
[variable_name] => pages
[variable_value] =>
[children] => array
(
[0] => array
(
[id] => 9
[parent_id] => 8
[variable_name] => child_category_page
[variable_value] =>
[children] => array
(
[0] => array
(
[id] => 10
[parent_id] => 9
[variable_name] => middle
[variable_value] =>
[children] => array
(
[0] => array
(
[id] => 11
[parent_id] => 10
[variable_name] => left
[variable_value] => {"name":"Companies", "link":"companies.html", "show":"1", "test":1},
),
),
),
),
),
),
),
),
),
)
I want to convert it into,
[
'menus' => [
'products' => [
'name' => 'Products',
'link' => 'cctv.html',
'show' => true,
],
'companies' => [
'name' => 'Companies',
'link' => 'companies.html',
'show' => true,
],
],
'breadcrumbs' => [
'news' => [
'text' => 'News',
'show' => true,
'link' => 'news.html',
],
'companies' => [
'text' => 'Companies',
'show' => true,
'link' => 'companies.html',
],
],
'products' => [
'pages' => [
'child_category_page' => [
'middle' => [
'left' => [
'text' => 'Companies',
'show' => true,
'link' => 'companies.html',
],
],
],
],
],
];
What I have tried is,
$data = DB::table("SITE_CONFIGS")->where("parent_id", 0)->get();
$data = get_tree_site_configs($data);
function get_tree_site_configs($data, $parent=0, &$result=[]){
$data = json_decode(json_encode($data),true);
$branch = [];
foreach ($data as $key => &$value) {
if($parent == $value['parent_id']){
$has_sub = DB::table("SITE_CONFIGS")->where("parent_id", $value['id'])->get();
$children = get_tree_site_configs($has_sub, $value['id'],$result);
if($children){
$value['children'] = $children;
}
// pr($value);
$branch[] = $value;
}
}
return $branch;
}
Note: There is parent-child relation to n-level, parent id with variable_value are leaf notes, means they don't have any children, rest all are parents of some records.
function get_tree_site_configs(array $config) {
$result = [];
foreach ($config as $item) {
if (isset($item['children'])) {
$value = get_tree_site_configs($item['children']);
} else {
$value = $item['variable_value'];
}
$result[$item['variable_name']] = $value;
}
return $result;
}
Example code array: https://eval.in/639002
A guest with (user_id = 1) bought multiple tickets (ticket_id = 1 & 2) On event (event_id = 11).
I am expecting the result format:
[ticket] => Array
(
[1] => Ticket Name, ***
[2] => Ticket Name
)
Code example below:
$data_db = array(
array(
'id' => 1,
'user_id' => 1,
'event_id' => 11,
'ticket_id' => 1,
'user_name' => 'guest 1'
),
array(
'id' => 2,
'user_id' => 2,
'event_id' => 11,
'ticket_id' => 1,
'user_name' => 'guest 2'
),
array(
'id' => 3,
'user_id' => 3,
'event_id' => 22,
'ticket_id' => 1,
'user_name' => 'guest 3'
),
array(
'id' => 4,
'user_id' => 1,
'event_id' => 11,
'ticket_id' => 2,
'user_name' => 'guest 1'
)
);
$output = [];
foreach ( $data_db as $key => $row ) {
$output[ $row['event_id'] ]['event'] = 'Event Name';
$output[ $row['event_id'] ]['attendee'][ $row['user_id'] ] = $row;
$output[ $row['event_id'] ]['attendee'][ $row['user_id'] ]['ticket'][ $row['ticket_id'] ] = 'Ticket Name';
}
print_r($output);
Current result
Array
(
[11] => Array
(
[event] => Event Name
[attendee] => Array
(
[1] => Array
(
[id] => 4
[user_id] => 1
[event_id] => 11
[ticket_id] => 2
[user_name] => guest 1
[ticket] => Array
(
[2] => Ticket Name
)
)
[2] => Array
(
[id] => 2
[user_id] => 2
[event_id] => 11
[ticket_id] => 1
[user_name] => guest 2
[ticket] => Array
(
[1] => Ticket Name ***
)
)
)
)
[22] => Array
(
[event] => Event Name
[attendee] => Array
(
[3] => Array
(
[id] => 3
[user_id] => 3
[event_id] => 22
[ticket_id] => 1
[user_name] => guest 3
[ticket] => Array
(
[1] => Ticket Name
)
)
)
)
)
First of you could start by sorting out an array of tickets of which ticket belongs to which user:
$output = [];
foreach($data_db as $key=>$row) {
// Define new $tickets Array E.g ['guest_name']=>['ticket_id']
$tickets[$row['user_name']][] = $row['ticket_id'];
$output [] = [
'id'=>$row['id'],
'user_id'=>$row['user_id'],
'event_id'=>$row['event_id'],
'user_name'=>$row['user_name'],
'tickets'=>[]
];
}
Your output of $tickets would look like:
Array
(
[guest 1] => Array
(
[0] => 1
[1] => 2
)
[guest 2] => Array
(
[0] => 1
)
[guest 3] => Array
(
[0] => 1
)
)
Then you can combine them, like this:
foreach($output as $k=>$v){
foreach($tickets as $guest=>$ticket){
if($v['user_name'] == $guest){
$output[$k]['tickets'] = $ticket;
}
}
}
Your output is:
Array
(
[0] => Array
(
[id] => 1
[user_id] => 1
[event_id] => 11
[user_name] => guest 1
[tickets] => Array
(
[0] => 1
[1] => 2
)
)
[1] => Array
(
[id] => 2
[user_id] => 2
[event_id] => 11
[user_name] => guest 2
[tickets] => Array
(
[0] => 1
)
........