How to merge multidimensional arrays where only subarrays are affected? [duplicate] - php

This question already has answers here:
Merge row data from multiple arrays
(6 answers)
Closed 5 months ago.
here: Transforming array values in elements of a subarray using PHP I asked quite the same, but the arrays were flatter. I tried to adapt the code, but unfortunately without success.
How could I merge following arrays so the second array won't be added after the end of the first array, but each subarray of the first array will receive the correspondent values of subarrays of the second. In other words, I want to merge the subarrays. Here my example:
Array 01:
Array01 (
[0] => Array
(
[0] => 40292633
[1] => 412
)
[1] => Array
(
[0] => 41785603
[1] => 382
)
[2] => Array
(
[0] => 48792980
[1] => 373
)
[3] => Array
(
[0] => 44741143
[1] => 329
))
Array 02:
Array02(
[0] => Array
(
[0] => 3460581
[1] => 1407424B1
[2] => 951753
)
[1] => Array
(
[0] => 3484251
[1] => 1028325B1
[2] => 159357
)
[2] => Array
(
[0] => 3519102
[1] => 0586365A1
[2] => 456654
)
[3] => Array
(
[0] => 3529714
[1] => 1059876A1
[2] => 852258
))
Final array:
finalArray(
[0] => Array
(
[0] => 40292633
[1] => 412
[2] => 3460581
[3] => 1407424B1
[4] => 951753
)
[1] => Array
(
[0] => 41785603
[1] => 382
[2] => 3484251
[3] => 1028325B1
[4] => 159357
)
[2] => Array
(
[0] => 48792980
[1] => 373
[2] => 3519102
[3] => 0586365A1
[4] => 456654
)
[3] => Array
(
[0] => 44741143
[1] => 329
[2] => 3529714
[3] => 1059876A1
[4] => 852258
))
Many thanks in advance!

try this code
function merge_arrays($a1, $a2) {
return array($a1, $a2);
}
$result = array_map("merge_arrays", $a1, $a2);
foreach($result as $nr)
{
$nres[] = array_merge ($nr[0], $nr[1]);
}

Try this:
$result = array();
$keys = array_unique( array_merge(array_keys($arr1), array_keys($arr2)) );
foreach($keys as $key) {
if( !array_key_exists($key, $arr1) ) {
$result[$key] = $arr2;
} else if( !array_key_exists($key, $arr2) ) {
$result[$key] = $arr1;
} else {
$result[$key] = array_merge($arr1[$key], $arr2[$key]);
}
}
It does not assume that both arrays have the same keys.
If you'd like to use array_map, this is an equivalent solution:
$keys = array_unique( array_merge(array_keys($arr1), array_keys($arr2)) );
$result = array_map(function($key) use ($arr1,$arr2) {
if( !array_key_exists($key, $arr1) ) {
return $arr2;
} else if( !array_key_exists($key, $arr2) ) {
return $arr1;
}
return array_merge($arr1[$key], $arr2[$key]);
},
$keys);
If you're sure both arrays have the same keys, you can try this:
$result = array();
foreach($arr1 as $key => $arr1val) {
$result[$key] = array_merge($arr1val, $arr2[$key]);
}

Related

manipulating multidimensional array

I have a multi-dimensional array. Since the value of the string "volvo" is present twice, I want to combine those keys. Here's the source array:
Array
(
[0] => Array
(
[0] => Volvo
[1] => 22
)
[1] => Array
(
[0] => BMW
[1] => 15
)
[2] => Array
(
[0] => Saab
[1] => 5
)
[3] => Array
(
[0] => Volvo
[1] => 17
)
)
and I'd like to convert it to this one:
Array
(
[0] => Array
(
[0] => Volvo
[1] => 39
)
[1] => Array
(
[0] => BMW
[1] => 15
)
[2] => Array
(
[0] => Saab
[1] => 5
)
)
I think this would make more sense to return an associated array, that way you can do $arr["volvo"], if you're fine with an associated array, just remove the second foreach loop.
If not, this will get the correct output:
<?php
$arr = Array (
Array (
"Volvo",
22
),
Array (
"BMW",
15
),
Array (
"Saab",
5
),
Array (
"Volvo",
17
)
);
$tmpNewArr = Array();
foreach ($arr as $ele) {
if (!isset($arr[$ele[0]])) {
$tmpNewArr[$ele[0]] = 0;
}
$tmpNewArr[$ele[0]] += $ele[1];
}
$newArr = [];
foreach ($tmpNewArr as $key => $ele) {
array_push($newArr,[$key,$ele]);
}
var_dump($newArr);
?>
Here's an eval.in:
https://eval.in/766340
$keyValueCars = [];
foreach($cars as $car){
$brand = $car[0];
$total = $car[1];
if(!isset($keyValueCars[$brand])){
$keyValueCars[$brand] = total;
}
else{
$keyValueCars[$brand] += total;
}
}
You could use
array_unique(Your_array, SORT_REGULAR);

How to concatenate arrays element recursively [duplicate]

This question already has answers here:
Joining similar data from two indexed arrays
(2 answers)
Closed 5 months ago.
I'm working on a project and I'm stacked since 2 days, this is my problem: I have two arrays and want to retrieve the second item in each object in Array_2 and concatenate it to the content of each object in first Array_1 in PHP.
Array_1
[[1453274700000,24011],[1453275000000,24222],[1453275300000,24284],[1453275600000,24331],...]
Array_2
[[1453274700000,51951],[1453275000000,52093],[1453275300000,52251],[1453275600000,52288],...]
Wanted_array
[[1453274700000,24011,51951],[1453275000000,24222,52093],[1453275300000,24284,52251],[1453275600000,24331,52288]...]
A functional solution:
$result = array_map(function (array $a1, array $a2) {
return array_merge($a1, [$a2[1]]);
}, $array_1, $array_2);
This assumes that all items are in order and only need to be merged by their order, not by their first value.
If you want $item[0] to define what "group" each value belongs to, you can iterate through the first array and save $item[0] as the key and $item[1] as the value. Do the same for the second array. Now iterate through the saved array for array1, and check if the saved array for array2 contains the same keys. Do the same for array2 (in case it has key that array1 doesn't have), and save it all to a new array:
<?php
$arr1 = array(
array('1453274700000',24011),
array('1453275000000',24222),
array('1453276000000',24222), // inexistent in $arr2
);
$arr2 = array(
array('1453275000000',52093),
array('1453274700000',51951),
array('1453273000000',24222), // inexistent in $arr1
);
$arr1dictionary = [];
$arr2dictionary = [];
$result = [];
foreach ($arr1 as $collection) {
$arr1dictionary[$collection[0]] = $collection[1];
}
foreach ($arr2 as $collection) {
$arr2dictionary[$collection[0]] = $collection[1];
}
foreach ($arr1dictionary as $key => $value) {
if (isset($arr2dictionary[$key])) {
$result[$key] = [$key, $value, $arr2dictionary[$key]];
} else {
$result[$key] = [$key, $value, null];
}
}
foreach ($arr2dictionary as $key => $value) {
if (isset($result[$key])) {
continue;
}
$result[$key] = [$key, null, $value];
}
$result = array_values($result);
print_r($result);
Output:
Array
(
[0] => Array
(
[0] => 1453274700000
[1] => 24011
[2] => 51951
)
[1] => Array
(
[0] => 1453275000000
[1] => 24222
[2] => 52093
)
[2] => Array
(
[0] => 1453276000000
[1] => 24222
[2] => (null, the value only exists in $arr1)
)
[3] => Array
(
[0] => 1453273000000
[1] => (null, the value only exists in $arr2)
[2] => 24222
)
)
DEMO
Use array_walk and add second item from $array2 if it exists.
$array1 = array(
array(1453274700000,24011),
array(1453275000000,24222),
array(1453275300000,24284),
array(1453275600000,24331)
);
$array2 = array(
array(1453274700000,51951),
array(1453275000000,52093),
array(1453275300000,52251),
array(1453275600000,52288),
);
array_walk($array1, function(&$item, $key) use ($array2){
if(isset($array2[$key][1])){
$item[] = $array2[$key][1];
}
});
print_r($array1);
Output
Array
(
[0] => Array
(
[0] => 1453274700000
[1] => 24011
[2] => 51951
)
[1] => Array
(
[0] => 1453275000000
[1] => 24222
[2] => 52093
)
[2] => Array
(
[0] => 1453275300000
[1] => 24284
[2] => 52251
)
[3] => Array
(
[0] => 1453275600000
[1] => 24331
[2] => 52288
)
)
EDIT
As #h2ooooooo pointed out that there could be possibility that array items are in random order. If array items can be in random order and they are matched with first index value, use this (works with PHP >= 5.5.0):
$array1 = array(
array(1453274700000,24011),
array(1453275000000,24222),
array(1453275300000,24284),
array(1453275600000,24331),
array(1453276000000,24222) // no match in $array2
);
$array2 = array(
array(1453275000000,52093),
array(1453274700000,51951),
array(1453275300000,52251),
array(1453275600000,52288),
);
array_walk($array1, function(&$item, $key) use ($array2){
// Find match in $array2
$array2_key = array_search($item[0], array_column($array2, 0));
// If match found
if($array2_key !== false && isset($array2[$array2_key][1])){
$item[] = $array2[$array2_key][1];
}
// No match
else{
$item[] = null;
}
});
print_r($array1);
OUTPUT
Array
(
[0] => Array
(
[0] => 1453274700000
[1] => 24011
[2] => 51951
)
[1] => Array
(
[0] => 1453275000000
[1] => 24222
[2] => 52093
)
[2] => Array
(
[0] => 1453275300000
[1] => 24284
[2] => 52251
)
[3] => Array
(
[0] => 1453275600000
[1] => 24331
[2] => 52288
)
[4] => Array
(
[0] => 1453276000000
[1] => 24222
[2] =>
)
)

PHP remove duplicate values from multidimensional array but keep last one

i have this array
$items = Array (
[0] => Array ( [0] => xx [1] => 'update')
[1] => Array ( [0] => bx [1] => 'update')
[2] => Array ( [0] => xx [1] => 'creation')
[3] => Array ( [0] => fs [1] => 'creation')
[4] => Array ( [0] => tx [1] => 'update')
[5] => Array ( [0] => bx [1] => 'creation')
)
i'm trying to remove duplicate values based on the first element (xx,bx,ax etc)
if two elements from the same table match, i'd like to keep the last one with higher index,
the result would be like the following
$items = Array (
[0] => Array ( [0] => xx [1] => 'creation')
[1] => Array ( [0] => bx [1] => 'creation')
[2] => Array ( [0] => fs [1] => 'creation')
[3] => Array ( [0] => tx [1] => 'update')
)
keeping the last one was a bit confusing to me as i'm new to PHP.
Thank you in advance
Generic deduplication:
$result = [];
foreach ($array as $item) {
$result[$item[0]] = $item;
}
Functional:
$result = array_reduce($array, function ($acc, $i) {
return [$i[0] => $i] + $acc;
}, [])
Awesome:
array_column($array, null, 0);
Well, i found the solution,
i started bu reversing the array, then executed the following code
$taken = array();
$reverse = array_reverse($items, true);
foreach($reverse as $key => $item) {
if(!in_array($item[0], $taken)) {
$taken[] = $item[0];
} else {
unset($reverse[$key]);
}
}

Recursive PHP Tree (permutations)

I'm looking to write a function which creates all permutation of a list of arrays (The list is dynamical). Now I found 2 articles, http://dannyherran.com/2011/06/finding-unique-array-combinations-with-php-permutations/ and Finding cartesian product with PHP associative arrays. But I don't want to store them as multiple arrays, I want to add each array to each possibility so I can use them later.
In fact I want to multiply each array with the other.
For example:
$array = array(
array(
1,
2
),
array(
'A',
'B',
'C'),
array(
'I',
'II')
);
In this form:
Array
(
[0] => Array
(
[0] => 1
[1] => Array
(
[0] => Array
(
[0] => A
[1] => Array
(
[0] => I
[1] => II
)
)
[1] => Array
(
[0] => B
[1] => Array
(
[0] => I
[1] => II
)
)
[2] => Array
(
[0] => C
[1] => Array
(
[0] => I
[1] => II
)
)
)
)
[1] => Array
(
[0] => 2
[1] => Array
(
[0] => Array
(
[0] => A
[1] => Array
(
[0] => I
[1] => II
)
)
[1] => Array
(
[0] => B
[1] => Array
(
[0] => I
[1] => II
)
)
[2] => Array
(
[0] => C
[1] => Array
(
[0] => I
[1] => II
)
)
)
)
)
I think this big example made my problem clear. For this type of array I created a function:
foreach ($array[1] as $value) {
$return1[] = array($value, $array[2]);
}
foreach ($array[0] as $value) {
$return[] = array($value, $return1);
}
print_r($return);
Now I want to create this function inside a recursive function (so it becomes dynamical) but I got stuck. I wanted to pass the amount of arrays to the function and then iterate.
function createTree($array, $loops=3){
$b = $array[$loops-2];
foreach ($b as $v) {
$return[] = array($v, createTree($return, $loops-1));
}
print_r($return);
}
Maybe there is a total other solution to multiply the arrays? But the function which isn't recursive is easy for me, but making it recursive...
Thanks for your help
function createTree($array){
switch(count($array)) {
case 0:
die('Illegal argument.');
case 1:
return $array[0];
default:
$lastArray = array_pop($array);
$subArray = createTree($array);
foreach ($lastArray as $item) {
$return[] = array($item, $subArray);
}
return $return;
}
}
var_dump(createTree(array_reverse($array)));

How to remove the parent numeric keys of php array

I've an array in php something like below
Array
(
[0] => Array
(
[0] => 40173
[1] => 514081
[2] => 363885
[3] => 891382
),
[1] => Array
(
[0] => 40173
[1] => 5181
[2] => 385
[3] => 891382
)
)
Now I want to remove the parents indexes 0,1... and finally want to get all the values (only unique values).
Thanks.
One possible approach is using call_user_func_array('array_merge', $arr) idiom to flatten an array, then extracting unique values with array_unique():
$new_arr = array_unique(
call_user_func_array('array_merge', $old_arr));
Demo. Obviously, it'll work with array of any length.
$startArray = Array
(
[0] => Array
(
[0] => 40173
[1] => 514081
[2] => 363885
[3] => 891382
),
[1] => Array
(
[0] => 40173
[1] => 5181
[2] => 385
[3] => 891382
)
);
//Edited to handle more the 2 subarrays
$finalArray = array();
foreach($startArray as $tmpArray){
$finalArray = array_merge($finalArray, $tmpArray);
}
$finalArray = array_unique($finalArray);
Using RecursiveArrayIterator Class
$objarr = new RecursiveIteratorIterator(new RecursiveArrayIterator($yourarray));
foreach($objarr as $v) {
$new_arr[]=$v;
}
print_r(array_unique($new_arr));
Demo
OUTPUT:
Array
(
[0] => 40173
[1] => 514081
[2] => 363885
[3] => 891382
[5] => 5181
[6] => 385
)
$new_array = array_merge($array1, $array2);
$show_unique = array_unique($new_array);
print_r($show_unique);
array_merge is merging the array's, array_unique is removinge any duplicate values.
Try something like this:
$new_array = array();
foreach($big_array as $sub_array) {
array_merge($new_array, $sub_array);
}
$new_array = array_unique($new_array);
(code not tested, this just a concept)
Try this:
$Arr = array(array(40173, 514081, 363885, 891382),
array(40173,5181, 385,891382));
$newArr = array();
foreach($Arr as $val1)
{
foreach($val1 as $val2)
{
array_push($newArr, $val2);
}
}
echo '<pre>';
print_r(array_unique($newArr));
Output:
Array
(
[0] => 40173
[1] => 514081
[2] => 363885
[3] => 891382
[5] => 5181
[6] => 385
)
Refer: https://eval.in/124240
--
Thanks

Categories