Nested array, replace alphabetical keys with numeric and keep structure - php

I have a nested array who is 4 levels deep.
I would like to replace the keys by numerical ones but not the meta level, this array should keep the alphabetical keys.
The array will have a lot of values and there will be more accounts like Marco Mueller, this is just a short example. It is important that it will keep the same nested structure, after its replaced by numerical keys.
$array = array (
'Marco Mueller' =>
array (
'meta' =>
array (
'accountName' => 'Marco Mueller',
'accountId' => '1',
'sum' => '3,659.06',
),
'Conrad, Ute' =>
array (
'meta' =>
array (
'customerName' => 'Conrad, Ute',
'customerId' => '8391',
'sum' => '457.59',
),
'Fidor Bank' =>
array (
'meta' =>
array (
'bankName' => 'Fidor Bank',
'bankKey' => 'FID',
'sum' => '457.59',
),
'H1-2019' =>
array (
'meta' =>
array (
'periodName' => 'H1-2019',
'periodId' => '5',
'sum' => '457.59',
),
),
),
),
),
);
The result should be
$array = array (
array (
'meta' =>
array (
'accountName' => 'Marco Mueller',
'accountId' => '1',
'sum' => '3,659.06',
),
'items' => array (
'meta' =>
array (
'customerName' => 'Conrad, Ute',
'customerId' => '8391',
'sum' => '457.59',
),
'items' =>
array (
'meta' =>
array (
'bankName' => 'Fidor Bank',
'bankKey' => 'FID',
'sum' => '457.59',
),
'items' => array (
'meta' =>
array (
'periodName' => 'H1-2019',
'periodId' => '5',
'sum' => '457.59',
),
),
),
array (
'meta' =>
array (
'periodName' => 'H2-2019',
'periodId' => '6',
'sum' => '600',
),
),
),
),
),
);

I solved my problem with this function, if anyone has an idea how to make this more elegant and efficient, your welcome!
private function getValues(array $array)
{
$newArray = [];
foreach ($array as $item) {
$meta = $item['meta'];
unset($item['meta']);
$arrayValues = array_values($item);
if (count($arrayValues) > 1 || count($arrayValues[0]) > 1) {
$arrayValues = $this->getValues($arrayValues);
}
if (!$arrayValues) {
$values = [
'meta' => $meta,
];
} else {
$values = [
'meta' => $meta,
'items' => $arrayValues,
];
}
$newArray[] = $values;
}
return $newArray;
}

Related

Inserting a new key if a particular key value matches in both the arrays

$array1 = array(
[0] => array(
'id' => 'gdye6378399sjwui39',
'name' => 'Plate 1'
),
[1] => array(
'id' => 'xyz6378399sjwui39',
'name' => 'Plate 2'
),
[2] => array(
'id' => 'tr2e6378399sjwui39',
'name' => 'Plate 3'
)
)
and another array
$array2 = array(
[0] => array(
'id' => 'gdye6378399sjwui39',
'ETA' => '8'
),
[1] => array(
'id' => 'tr2e6378399sjwui39',
'ETA' => '9'
)
[2] => array(
'id' => 'xyz6378399sjwui39',
'ETA' => '5'
)
)
I want to compare the two arrays. I am doing it like this way:-
if(!empty($array2))
{
foreach($array1 as $ck => $cl)
{
foreach($array12 as $ued){
if($cl['id'] == $ued['id'])
{
$array1[$ck]['ETA'] = $ued['ETA'];
break;
}
}
}
What are the other better ways to do this? The order of the two arrays may vary, and so does the size.
If you index the second array by the id (using array_column()) you can get away without using the inner foreach() and just use isset()...
$match = array_column($array2, null, 'id');
foreach ( $array1 as $ck=>$cl) {
if ( isset($match[$cl['id']]) ) {
$array1[$ck]['ETA'] = $match[$cl['id']]['ETA'];
}
}
print_r($array1);

Finding duplicate values in a multidimensional array for Search Method

My Code was :
$data = array();
foreach ($table as $key => $var) {
$data[] = ['id' => $var->id, 'value' => $var->designation];
}
My Data array should be like this
array (
0 => array (
'id' => 27,
'value' => 'laravel',
),
1 => array (
'id' => 1,
'value' => 'laravel tester',
),
2 => array (
'id' => 22,
'value' => 'laravel developer',
),
3 => array (
'id' => 23,
'value' => 'laravel casts',
),
4 => array (
'id' => 24,
'value' => 'laravel developer',
),
)
I need only one value i tried all the php core library function output:
array (
0 =>
array (
'id' => 27,
'value' => 'laravel',
),
1 => array (
'id' => 1,
'value' => 'laravel tester',
),
2 => array (
'id' => 23,
'value' => 'laravel casts',
),
3 => array (
'id' => 24,
'value' => 'laravel developer',
),
)
Based on the name only i need to remove duplicate bacause in my search bar it shows repeated mode.
You can use array_unique, wich saves indexes, and get the result by array_intersect_key
$temp = array_unique(array_column($arr, 'value'));
$res = array_intersect_key($arr, $temp);
print_r($res);

Search in array with N level nesting = recursive search in array (on keys)

Here is an array. Once a new element comes in with parent_uuid, I need to add that to the corresponding position, that is to the children of the item which has uuid value as parent_uuid value. The children then can have other children and if that is specified, I need to insert it to the particular parent. I think for this I need to search to the multidimensional array with the parent_uuid value. How can I do this and insert in PHP?
Array
(
[0] => Array
(
[id] => 1
[uuid] => ef4b72ae-012a-4b2c-88b2-d4bf8726fcb9
[parent_uuid] =>
[name] => First Parent
[children] => Array
(
)
)
[1] => Array
(
[id] => 2
[uuid] => 74bd4b37-6a20-4579-99a3-ce56b0bc28a7
[parent_uuid] =>
[name] => Second Parent
[children] => Array
(
[0] => Array
(
[id] => 3
[uuid] => f87c6d5c-93ec-40bf-a04d-c925dd1e0aca
[parent_uuid] => 74bd4b37-6a20-4579-99a3-ce56b0bc28a7
[name] => First Child
[children] => Array
(
)
)
[1] => Array
(
[id] => 4
[uuid] => cb2b3d9d-867c-40a0-9254-05b466859db1
[parent_uuid] => 74bd4b37-6a20-4579-99a3-ce56b0bc28a7
[name] => Second Child
[children] => Array
(
)
)
)
)
)
I think you need some kind of recursive function, here is my messy example.
<?php
header('Content-type: text/plain');
$data = array (
0 =>
array (
'id' => 1,
'uuid' => 'ef4b72ae-012a-4b2c-88b2-d4bf8726fcb9',
'parent_uuid' => '',
'name' => 'First Parent',
'children' =>
array (
),
),
1 =>
array (
'id' => 2,
'uuid' => '74bd4b37-6a20-4579-99a3-ce56b0bc28a7',
'parent_uuid' => '',
'name' => 'Second Parent',
'children' =>
array (
0 =>
array (
'id' => 3,
'uuid' => 'f87c6d5c-93ec-40bf-a04d-c925dd1e0aca',
'parent_uuid' => '74bd4b37-6a20-4579-99a3-ce56b0bc28a7',
'name' => 'First Child',
'children' =>
array (
),
),
1 =>
array (
'id' => 4,
'uuid' => 'cb2b3d9d-867c-40a0-9254-05b466859db1',
'parent_uuid' => '74bd4b37-6a20-4579-99a3-ce56b0bc28a7',
'name' => 'Second Child',
'children' =>
array (
),
),
),
),
);
function arrayAddChild(&$data, $child) {
if (!isset($data) || !is_array($data) || empty($data)) {
return false;
}
foreach ($data as $key => $value) {
if ($value['uuid'] === $child['parent_uuid']) {
$data[$key]['children'][] = $child;
return true;
}
if(arrayAddChild($data[$key]['children'], $child)) {
return true;
}
}
return false;
}
var_export(arrayAddChild($data, [
'id' => 31,
'uuid' => '31',
'parent_uuid' => 'cb2b3d9d-867c-40a0-9254-05b466859db1',
'name' => 'Second Child',
'children' => []
]
));
var_export(arrayAddChild($data, [
'id' => 32,
'uuid' => '32',
'parent_uuid' => '31',
'name' => 'Second Child',
'children' => []
]
));
var_export(arrayAddChild($data, [
'id' => 33,
'uuid' => '33',
'parent_uuid' => '32',
'name' => 'Second Child',
'children' => []
]
));
var_export(arrayAddChild($data, [
'id' => 34,
'uuid' => '34',
'parent_uuid' => '33',
'name' => 'Second Child',
'children' => []
]
));
var_export(arrayAddChild($data, [
'id' => 35,
'uuid' => '35',
'parent_uuid' => '34',
'name' => 'Second Child',
'children' => []
]
));
var_export(arrayAddChild($data, [
'id' => 36,
'uuid' => '36',
'parent_uuid' => '35',
'name' => 'Second Child',
'children' => []
]
));
var_export($data);
this is the structure you need
$Array["ef4b72ae-012a-4b2c-88b2-d4bf8726fcb9"]['name'] = "First Parent";
$Array["ef4b72ae-012a-4b2c-88b2-d4bf8726fcb9"]['children'] = [];
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['name'] = "Second Parent";
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['children']["f87c6d5c-93ec-40bf-a04d-c925dd1e0aca"]['name'] = "First Child";
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['children']["f87c6d5c-93ec-40bf-a04d-c925dd1e0aca"]['children'] = [];
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['children']["cb2b3d9d-867c-40a0-9254-05b466859db1"]['name'] = "Second Child";
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['children']["cb2b3d9d-867c-40a0-9254-05b466859db1"]['children'] = [];
and this is if you really need 'name' or any complementary info you need to store with each item. If it is just about a tree structure of uid, get rid of 'name' and 'children' keys
have not found a standard php function to recursively search for a given key (anyone ?)
so here is the function you need
function insertItem($newItem,$uidParent,$array) {
foreach ($array as $uid => $content) {
if ($uid == $uidParent) { // parent found, item insert
$array[$uid]['children'][$newItem['uid']]['name'] = $newItem['name'];
$array[$uid]['children'][$newItem['uid']]['children'] = [];
} elseif (!empty($content['children'])) { // recursively search the tree
$array[$uid]['children'] = insertItem($newItem,$uidParent,$content['children']);
}
}
return $array;
}
$newItem['name'] = "new item";
$newItem['uid'] = "f87c6d5c-93ec-40bf-a04d-c925dd1e0aca";
$uidParent = "cb2b3d9d-867c-40a0-9254-05b466859db1";
$Array = insertItem($newItem,$uidParent,$Array);
sandbox here

convert indexed multidimensional array to associative multidimensional array

I have an indexed array with nested categories like this:
array (
0 =>
array (
'name' => 'Furniture',
'id' => 'b3cdd1k',
'content' =>
array (
0 =>
array (
'name' => 'Tables',
'id' => 'nw24ga3',
'content' =>
array (
0 =>
array (
'name' => 'Wooden tables',
'id' => 'ba5lgaz',
),
1 =>
array (
'name' => 'Glass tables',
'id' => 'rqt91gz',
),
),
),
),
),
1 =>
array (
'name' => 'Lamps',
'id' => 'vb1a4nf',
),
2 =>
array (
'name' => 'Doors',
'id' => 'a5l4gal',
'content' =>
array (
0 =>
array (
'name' => 'Entrance doors',
'id' => 'qwg30fb',
),
),
),
)
Is there elegant way to convert it to associative array (where keys are id's) and keep nesting structure?
After conversion I excepting something like this:
array (
'b3cdd1k' =>
array (
'name' => 'Furniture',
'content' =>
array (
'nw24ga3' =>
array (
'name' => 'Tables',
'content' =>
array (
'ba5lgaz' =>
array (
'name' => 'Wooden tables',
),
'rqt91gz' =>
array (
'name' => 'Glass tables',
),
),
),
),
),
'vb1a4nf' =>
array (
'name' => 'Lamps',
),
'a5l4gal' =>
array (
'name' => 'Doors',
'content' =>
array (
'qwg30fb' =>
array (
'name' => 'Entrance doors',
),
),
),
)
You could try this - not the most elegant, but seems to work:
function convert(&$a)
{
$result = Array();
foreach($a as $k=>&$v)
{
$result[$v['id']]['name'] = $v['name'];
if(is_array($v['content'])) $result[$v['id']]['content'] = convert($v['content']);
}
return $result;
}
if(count($array) != 0) $result = convert($array);

Merge and group rows from multiple 2d arrays based on a shared column value then push another column's data into subarrays

Scenario:
I have these 2 arrays:
array1:
Array
(
[1] => Array
(
[label] => pending
[fillColor] => #468847
[data] => 50
)
[2] => Array
(
[label] => dispatched
[fillColor] => #6ecf70
[data] => 10
)
[3] => Array
(
[label] => delivered
[fillColor] => #f89406
[data] => 1
)
[4] => Array
(
[label] => invoiced
[fillColor] => #3a87ad
[data] => 2
)
)
array2:
Array
(
[1] => Array
(
[label] => pending
[fillColor] => #468847
[data] => Array
(
[0] => 1
)
)
)
The result I need is
Array
(
[1] => Array
(
[label] => pending
[fillColor] => #468847
[data] => Array
(
[0] => 50
[1] => 1
)
)
[2] => Array
(
[label] => dispatched
[fillColor] => #6ecf70
[data] => Array
(
[0] => 10
[1] => 0
)
)
[3] => Array
(
[label] => delivered
[fillColor] => #f89406
[data] => Array
(
[0] => 1
[1] => 0
)
)
[4] => Array
(
[label] => invoiced
[fillColor] => #3a87ad
[data] => Array
(
[0] => 2
[1] => 0
)
)
)
There are only 4 labels:
pending
dispatched
delivered
invoiced
Please note that the arrays are just an example. It can happen that the first array has no values at all or just 2 and the second array have 3 values or none.
Because of that constraint above I'm thinking to use array_replace and having an array called
base_array = ["pending", "dispatched", "delivered", "invoiced"]
I have tried to loop the base_array and try to match the array1 with array2 if label exist.
Basically, if key (which is label) is not exist in any of array1 or array2 then the value replaced will be 0 in the resulting array.
I have tried
foreach($base_array as $key => $value) {
if(in_array($key, $array1[$key])) {
$array[$key] = $array1[$key];
}
}
but it looks like I'm lost on these multi dimensional arrays and replacing. Any help will be really appreciated. Thanks.
From what i understand from your question you can do it like this :-
$array = array(
'1' => Array
(
'label' => 'pending',
'fillColor' => '#468847',
'data' => '50'
),
'2' => Array
(
'label' => 'dispatched',
'fillColor' => '#6ecf70',
'data' => '10'
),
'3 ' => Array
(
'label' => 'delivered',
'fillColor' => '#f89406',
'data' => '1'
),
'4' => Array
(
'label' => 'invoiced',
'fillColor' => '#3a87ad',
'data' => '2'
),
);
$array2 = array
(
'1' => Array
(
'label' => 'pending',
'fillColor' => '#468847',
'data' => array
(
'0' => '1'
)
)
);
$temp = array();
$i = 0;
foreach ($array as $key => $value) {
$temp[$key]['label'] = $value['label'];
$temp[$key]['fillColor'] = $value['fillColor'];
foreach ($array2 as $key2 => $value2) {
if ($value['fillColor'] == $value2['fillColor'] && $value['label'] == $value2['label']) {
$temp[$key]['data'][] = $value['data'];
if (isset($value2['data'][$i])) {
$temp[$key]['data'][] = $value2['data'][$i];
}
} else {
$temp[$key]['data'][] = $value['data'];
if (!isset($value2['data'][$i])) {
$temp[$key]['data'][] = 0;
}
}
$i++;
}
}
echo '<pre>';
print_r($temp);
Try this out:
$array1 = array(
array(
'label' => 'pending',
'fillColor' => '#468847',
'data' => '50'
),
array(
'label' => 'dispatched',
'fillColor' => '#468847',
'data' => '10'
),
array(
'label' => 'delivered',
'fillColor' => '#468847',
'data' => '8'
),
array(
'label' => 'invoiced',
'fillColor' => '#468847',
'data' => '5'
)
);
$array2 = array(
array(
'label' => 'pending',
'fillColor' => '#468847',
'data' => array()
),
array(
'label' => 'dispatched',
'fillColor' => '#6ecf70',
'data' => array()
),
array(
'label' => 'delivered',
'fillColor' => '#f89406',
'data' => array()
),
array(
'label' => 'invoiced',
'fillColor' => '#3a87ad',
'data' => array()
)
);
foreach ($array1 as $order) {
foreach ($array2 as $key => $group) {
if ($order['label'] == $group['label']) {
array_push($array2[$key]['data'], $order['data']);
}
}
}
var_dump($array2);
Declare an array of default rows with empty data values.
Merge the default array, the first array, thrn the second array into one array.
Iterate the merged array's rows.
Declare reference arrays which are identified by label values. Explicitly cast each encountered data value as an array before joining into its group's subarray.
Code: (Demo)
$defaults = [
['label' => 'pending', 'fillColor' => '#468847', 'data' => []],
['label' => 'dispatched', 'fillColor' => '#6ecf70', 'data' => []],
['label' => 'delivered', 'fillColor' => '#f89406', 'data' => []],
['label' => 'invoiced', 'fillColor' => '#3a87ad', 'data' => []],
];
$result = [];
foreach (array_merge($defaults, $array1, $array2) as $row) {
$label = $row['label'];
$row['data'] = (array) $row['data'];
if (!isset($ref[$label])) {
$ref[$label] = $row;
$result[] = &$ref[$label];
} else {
$ref[$label]['data'] = array_merge(
$ref[$label]['data'],
$row['data']
);
}
}
var_export($result);

Categories