multidimensional array merge operation inside loop - php

let's say I have two arrays like so:
$array1 = array('A' => array(
'B' => array(
'C' => array(
'D' => array(
'data' => array(
0 => array(
'id' => 1,
'name' => 'name 1'),
1 => array(
'id' => 2,
'name' => 'name 2')))))));
$array2 = array('A' => array(
'B' => array(
'C' => array(
'E' => array(
'data' => array(
0 => array(
'id' => 3,
'name' => 'name 3'),
1 => array(
'id' => 4,
'name' => 'name 4')))))));
As you can see, the two arrays have the same key A, B, and C but the keys are different afterwards. How do I merge these two arrays into something like this:
$final_array = array('A' => array(
'B' => array(
'C' => array(
'D' => array(
'data' => array(
0 => array(
'id' => 1,
'name' => 'name 1'),
1 => array(
'id' => 2,
'name' => 'name 2'))),
'E' => array(
'data' => array(
0 => array(
'id' => 3,
'name' => 'name 3'),
1 => array(
'id' => 4,
'name' => 'name 4')))))));
As you can see, in this case I merge the arrays together into the same array that contains different keys for both. In order words, here I'm putting the array starting from key E from the second array into the array with index C.
Any help will be appreciated, thanks
EDIT: Now, how about if my arrays ($array1, $array2, $array3, $array4, etc...) are generated inside a foreach loop, how do I merge all of those arrays together (Notice that I do not know the number of arrays beforehand)

http://php.net/manual/en/function.array-merge-recursive.php
print_r(array_merge_recursive($array1, $array2));
This should do the trick.
Added:
$collection=array();
foreach() {
$collection[]=$myArray; //here you add your array to collection
}
print_r(call_user_func_array('array_merge_recursive', $collection));

i have not tested this but try this code:
foreach( $array1 as $key => $val )
{
if( !in_array( $key, $array2 ) )
{
$array2[$key] = $val;
}
}
EDIT
use Rok Kralj's answer, using native functions are probably the best way to do this as they are much faster.

Related

Merge php array with dynamic key

If I query out the array like this form:
$arr1:
0 =>
'id' => 1,
'name' => 'a'
1 =>
'id' => 2,
'name' => 'b'
2 =>
'id' => 3,
'name' => 'c'
3 =>
'id' => 4,
'name' => 'd'
$arr2:
0 =>
'id' => 1,
'parent' => '1a'
1 =>
'id' => 2,
'parent' => '2b'
2 =>
'id' => 3,
'parent' => '3c'
3 =>
'id' => 4,
'parent' => '4d'
When I need to merge these two I can done it using foreach loop.
The problem comes to when the $arr1 is dynamic data(need to use for pagination), i can't merge well using array_merge due to $arr2 is fixed data.
example:
first time:
$arr1:
0 =>
'id' => 1,
'name' => 'a'
1 =>
'id' => 2,
'name' => 'b'
$arr2:
0 =>
'id' => 1,
'parent' => '1a'
1 =>
'id' => 2,
'parent' => '2b'
2 =>
'id' => 3,
'parent' => '3c'
3 =>
'id' => 4,
'parent' => '4d'
second time:
$arr1:
0 =>
'id' => 3,
'name' => 'c'
1 =>
'id' => 4,
'name' => 'd'
$arr2:
0 =>
'id' => 1,
'parent' => '1a'
1 =>
'id' => 2,
'parent' => '2b'
2 =>
'id' => 3,
'parent' => '3c'
3 =>
'id' => 4,
'parent' => '4d'
I had try using foreach loop
foreach($arr1 as $k => $value){
$group[$k]['parent'] = $arr2[$k]['parent'];
$group[$k]['name'] = $value['name'];
$group[$k]['id'] = $value['id'];
}
It comes to the parent value does not change as $key is fixed.
The expected output should all the element in 1 array:
0 =>
'id' => 1,
'parent' => '1a'
'name'='a'
1 =>
'id' => 2,
'parent' => '2b'
'name'='b'
I think this is what you need...
The easiest way to do this is to re-index the second array with the ID as the key. I use array_column() to do this. Then use the id from $arr1 to access the parent value from the newly indexed array...
$parent = array_column($arr2, 'parent', 'id');
$group = [];
foreach($arr1 as $k => $value){
$group[$k]['parent'] = $parent[$value['id']];
$group[$k]['name'] = $value['name'];
$group[$k]['id'] = $value['id'];
}
In case $arr2 has more information, just use null as the second parameter to array_column(). Then you need to add the column name when you access that array...
$parent = array_column($arr2, null, 'id');
$group = [];
foreach($arr1 as $k => $value){
$group[$k]['parent'] = $parent[$value['id']]['parent'];
$group[$k]['name'] = $value['name'];
$group[$k]['id'] = $value['id'];
}
Try this:
foreach($arr1 as $k=>$v) {
$arr1[$k]['parent'] = $arr2[$k]['parent'];
}
print_r( $arr1 );

How to extract an array with multiple array keys and values to another array?

Please note that my php version is not 7.
I have an array of arrays like:
array(
'0' => array('id'=>1,'name'=>'abc',"class"=>'xyz'),
'1' => array('id'=>2,'name'=>'abc1',"class"=>'xyz1'),
'2' => array('id'=>3,'name'=>'abc',"class"=>'xyz2'),
);
I want to extract it into two arrays. like
array(
'0' => array('id'=>1,'name'=>'abc'),
'1' => array('id'=>2,'name'=>'abc1'),
'2' => array('id'=>3,'name'=>'abc'),
);
array(
'0' => array('id'=>1,"class"=>'xyz'),
'1' => array('id'=>2,"class"=>'xyz1'),
'2' => array('id'=>3,"class"=>'xyz2'),
);
How can i achieve this, I am in search of some built-in function etc, I studied its supported with array_column but with versions higher than 7.
Edit:
I also tried array_intersect_key and array_slice but its working with single dimensional array.
Then you might want to keep it simple and just use a straight forward foreach loop like this
$old = array(
array('id'=>1,'name'=>'abc',"class"=>'xyz'),
array('id'=>2,'name'=>'abc1',"class"=>'xyz1'),
array('id'=>3,'name'=>'abc',"class"=>'xyz2')
);
foreach ( $old as $temp ) {
$new1 = array('id' => $temp['id'], 'name' => $temp['name']);
$new2 = array('id' => $temp['id'], 'class' => $temp['class']);
}
Use a foreach and add the values to a new array for example:
$idsNames = [];
$idsClasses = [];
$items = [
array('id' => 1, 'name' => 'abc', "class" => 'xyz'),
array('id' => 2, 'name' => 'abc1', "class" => 'xyz1'),
array('id' => 3, 'name' => 'abc', "class" => 'xyz2'),
];
foreach ($items as $item) {
$idsNames[] = ["id" => $item["id"], "name" => $item["name"]];
$idsClasses[] = ["id" => $item["id"], "class" => $item["class"]];
}

Transform keys and values in an associative array

I have 2 associative Arrays but they are in the wrong form. The first
Array(
'name' => 'adam',
'age' => '13'
)
and the second one shoulb be combined (merged?)
Array(
'key' => 'pet',
'value' => 'dog'
)
that the result would be like
Array(
'name' => 'adam',
'age' => '13',
'pet' => 'dog'
)
Can anyone give me a hint/solution?
EDIT: I did it that way:
$result = array_merge($item, array_column($metas, 'v', 'k'));
Thanks
$data1 = Array(
'name' => 'adam',
'age' => '13'
);
$data2 = Array(
'key' => 'pet',
'value' => 'dog'
);
let $result=[];
foreach ($data1 as $key => $value) {
$result[$data2['key']]=$data2['value'];
$result=$data1+$result;
}
print_r($result);

php usort() with order of precedence for json sorting

I need to sort a json array with key value pair in a certain order of precedence(specialcharacters > numbers > lower case > uppercase). I tried with ascii code but couldn't get as expected.
$arr1 = array (
0 =>
array (
'id' => 1,
'name' => 'B',
'value' => 'abc',
'order' => 6,
),
1 =>
array (
'id' => 2,
'name' => 'a',
'value' => 'xyz',
'order' => 2,
),
2 =>
array (
'id' => 3,
'name' => 'A',
'value' => 'ghi',
'order' => 1,
),
3 =>
array (
'id' => 4,
'name' => '123',
'value' => 'xyz',
'order' => 2,
),
4 =>
array (
'id' => 5,
'name' => 'd',
'value' => 'uvw',
'order' => 3,
),
5 =>
array (
'id' => 6,
'name' => '#2',
'value' => 'def',
'order' => 3,
),
);
function cmp($a, $b)
{
$at = iconv('UTF-8', 'ASCII//TRANSLIT', $a['name']);
$bt = iconv('UTF-8', 'ASCII//TRANSLIT', $b['name']);
return strcmp($at, $bt);
}
usort($arr1, "cmp");
print_r($arr1);
Can anyone help me to resolve it?
<?php
// Obtain a list of columns
foreach ($arr1 as $key => $row) {
$arr1[$key] = $row['value'];
}
ksort($arr1);
?>

PHP - structure multidimensional array depending on values

I have an array:
$initialarray = array(
0 = array(
'unit' => 1,
'class' => 1,
'value' => 'string1'
),
1 = array(
'unit' => 1,
'class' => 2,
'value' => 'string2'
),
2 = array(
'unit' => 1,
'class' => 2,
'value' => 'string3'
),
3 = array(
'unit' => 2,
'class' => 1,
'value' => 'string4'
)
4 = array(
'unit' => 2,
'class' => 2,
'value' => 'string5'
)
);
What would be the best way to structure it (to group the resulting sub-arrays) depending first on the 'unit' field's values, and then depending on the 'class' field's values, like so:
$resultarray = array(
// array of all the sub-arrays of 'unit' = 1
$unit[1] = array(
// array of all the sub-arrays of 'unit' = 1 and 'class' = 1
$class[1] = array(
0 = array(
'unit' => 1,
'class' => 1,
'value' => 'string1'
)
)
// array of all the sub-arrays of 'unit' = 1 and 'class' = 2
$class[2] = array(
0 = array(
'unit' => 1,
'class' => 2,
'value' => 'string2'
),
1 = array(
'unit' => 1,
'class' => 2,
'value' => 'string3'
)
)
)
// array of all the sub-arrays of 'unit' = 2
$unit[2] = array(
// array of all the sub-arrays of 'unit' = 2 and 'class' = 1
$class[1] = array(
0 = array(
'unit' => 2,
'class' => 1,
'value' => 'string4'
)
)
// array of all the sub-arrays of 'unit' = 2 and 'class' = 2
$class[2] = array(
0 = array(
'unit' => 2,
'class' => 2,
'value' => 'string5'
)
)
)
)
I have asked a similar question here and got a working answer for only one iteration, i.e. for only structuring the array by one of the fields. But I could not make the same solution work for multiple iterations, i.e. for more than one field.
Also, is there a solution to structure a multidimensional array depending on more than two fields?
I think it's not a way of asking the question. It is very simple , you can do this by playing with arrays,keys and etc.... So first you should try hard for the problem. After If you have any problem in the middle of your tries then you can ask that here. I have solved your problem here is the complete code , but next time please do some work and then only post the problem. Never ask for the code.
foreach ($initialarray as $key1=>$val1)
{
foreach ($val1 as $key2=>$val2)
{
if($key2=='unit')
{
$num=$val2;
if($val2!=$num)
$testarr['unit'.$val2]=array();
}
if($key2=='class')
{
$testarr['unit'.$num]['class'.$val2][]=$val1;
}
}
}
print_r($testarr);
I must offer a better way for you and future researchers...
You only need one loop, and you merely need to nominate the result array's key values before using [] to "push" new data into the deepest subarray.
*there is absolutely no need for any condition statements or a second loop.
Code: (Demo)
$initialarray = [
['unit' => 1, 'class' => 1, 'value' => 'string1'],
['unit' => 1, 'class' => 2, 'value' => 'string2'],
['unit' => 1, 'class' => 2, 'value' => 'string3'],
['unit' => 2, 'class' => 1, 'value' => 'string4'],
['unit' => 2, 'class' => 2, 'value' => 'string5']
];
foreach ($initialarray as $row) {
$result[$row['unit']][$row['class']][] = $row;
}
var_export($result);
Output:
array (
1 =>
array (
1 =>
array (
0 =>
array (
'unit' => 1,
'class' => 1,
'value' => 'string1',
),
),
2 =>
array (
0 =>
array (
'unit' => 1,
'class' => 2,
'value' => 'string2',
),
1 =>
array (
'unit' => 1,
'class' => 2,
'value' => 'string3',
),
),
),
2 =>
array (
1 =>
array (
0 =>
array (
'unit' => 2,
'class' => 1,
'value' => 'string4',
),
),
2 =>
array (
0 =>
array (
'unit' => 2,
'class' => 2,
'value' => 'string5',
),
),
),
)
If I may express myself in the following manner: I only see the front-end of your problem and know nothing about its back-end, e.g. "Where does the data come from?", "How is it collected and stored", etc. so my answer might not be a real help but still I'll give my "tuppence".
If you can store all that data in a relational database (in form of table(s)) it would be much more easier and faster(!) to select the needed data from the database instead of rearranging arrays, which will take some more time in comparison.
Just as an example you might then select (and store it into an array) all items which have unit = '1' and / or all items which have class = '2'. That would make life much more easier IMHO, than having all the data in a multidimensional array and then try to sort it / rearrange it. Especially if you do that based on more than one property.

Categories