Related
This question already has answers here:
Push elements from one array into rows of another array (one element per row)
(4 answers)
Closed 5 months ago.
I need to evenly/synchronously push values from my second array into the rows of my first array.
The arrays which have the same size, but with different keys and depths. The first is an array of rows and the second is a flat array.
$array1 = [
12 => [130, 28, 1],
19 => [52, 2, 3],
34 => [85, 10, 5]
]
$array2 = [4, 38, 33]
Preferred result:
[
12 => [130, 28, 1, 4],
19 => [52, 2, 3, 38],
34 => [85, 10, 5, 33]
]
(I would like to keep the same indices of array 1, however it is not mandatory.)
I have tried these methods, but none of them work because the first array keys are unpredictable.
$final = [];
foreach ($array1 as $idx => $val) {
$final = [$val, $array2[$idx]];
}
Another:
foreach ($array1 as $index => $subArray) {
$array1 [$index][] = $array2[$index];
}
Here is one way to do this:
$merged = array_map('array_merge', $array1, array_chunk($array2, 1));
$result = array_combine(array_keys($array1), $merged);
The second step with array_combine is necessary to reapply the non-sequential keys because array_map won't preserve them in the first step.
An example using foreach
<?php
$a = [
2 => [130, 28, 1, 1, 6],
3 => [52, 2, 3, 3, 27]
];
$b = [5, 38];
$output = [];
$idx = 0;
foreach ($a as $key => $value) {
$value[] = $b[$idx];
$output[$key] = $value;
++$idx;
}
print_r($output);
Sandbox HERE
You can loop $array1 using a foreach to get the current key $index
Get the value from $array2 by using a counter as the array key which, is incremented by 1 for every iteration.
Then add the value to the end of the current array.
$array1 = [
2 => [130, 28, 1, 1, 6],
3 => [52, 2, 3, 3, 27],
13 => [41, 20, 27, 13, 37]
];
$array2 = [89, 99, 109];
$counter = 0;
foreach ($array1 as $index => $subArray) {
$array1[$index][] = $array2[$counter++];
}
print_r($array1);
Output
Array
(
[2] => Array
(
[0] => 130
[1] => 28
[2] => 1
[3] => 1
[4] => 6
[5] => 89
)
[3] => Array
(
[0] => 52
[1] => 2
[2] => 3
[3] => 3
[4] => 27
[5] => 99
)
[13] => Array
(
[0] => 41
[1] => 20
[2] => 27
[3] => 13
[4] => 37
[5] => 109
)
)
See a PHP demo.
Maintaining a counter while iterating is a simple way of accessing second array values while iterating the first. It is not necessary to make multiple passes of the arrays, just one iteration is all that is required.
Codes: (Demos)
a mapper:
$i = -1;
var_export(
array_map(fn($row) => array_merge($row, [$array2[++$i]]), $array1)
);
a looper:
$i = -1;
foreach ($array1 as &$row) {
array_push($row, $array2[++$i]);
}
var_export($array1);
a walker:
$i = -1;
array_walk($array1, fn(&$row, $k) => array_push($row, $array2[++$i]));
var_export($array1);
If you don't care about preserving the first array's keys in the result array, then you can simply use:
var_export(
array_map('array_merge', $array1, array_chunk($array2, 1))
);
I have these two arrays as output:
Value Array
(
[0] => 10100153
[1] => 2007
[2] => 350
[3] => 804082
[4] => WW006
[5] => WHT/NNY/OXGM
[6] => 35/38
[7] => 804082 WW00635/38
[8] => 0,00138857
[9] => Champion 3pk Quarter Socks
)
Numbers Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
[9] => 10
)
I want to combine them and change the key value of the value array in value and the numbers array in numbers, so it looks something like this:
Desire output
['Value' => '10100153', 'Number' => 1],
['Value' => '2007', 'Number' => 2],
['Value' => '390', 'Number' => 3],
['Value' => '804715', 'Number' => 4],
['Value' => 'WW001', 'Number' => 5],
['Value' => 'WHT/WHT/WHT', 'Number' => 6],
['Value' => '39/42', 'Number' => 7],
['Value' => '804715 WW00139/42', 'Number' => 8],
['Value' => '0.00138857', 'Number' => 9],
['Value' => '3pk Quarter Socks', 'Number' => 10]
All I can find is array_combine and array_merge, but array_merge just adds the numbers array to the end of the value array, and array_combine adds the numbers to the end of the text of the value array
You can use array_map (doc) and array_combine (doc) as:
$res = array_map(null, $valuesArray, $numbersArray);
$keys = array("Value", "Number");
$res = array_map(function ($e) use ($keys) {return array_combine($keys, $e);}, $res);
Notice the use of null in array_map. From documentation:
An interesting use of this function is to construct an array of arrays, which can be easily performed by using NULL as the name of the callback function
This way you can merge more arrays - just remember to add the correct key to $keys
Live example: 3v4l
You could use a regular foreach loop to iterate over your values array. At each element in the values array you can get its corresponding element in the numbers array by using the current index.
At each iteration (each loop of your values array) you can add an associative array into a resulting array (here I called it $res).
See example below:
$values = ["10100153", "2007", "350", "804082", "WW006", "WHT/NNY/OXGM", "35/38", "804082 WW00635/38", "0,00138857", "Champion 3pk Quarter Socks"];
$nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$res = []; // create empty array to hold associative arrays
foreach($values as $i=>$val) { // loop over your values array, where the index is $i and the value is $val
$num = $nums[$i]; // get the number at the given index
$res[$i] = ["Value" => $val, "Number" => $num]; // set the index in the resulting array to hold a newly formed associative array
}
print_r($res); // print the results
You can skip the extra round of iterating (while transposing with array_map(null...)) as demonstrated in dWinder's answer by passing both input arrays into array_map() and using the splat operator to receive the arguments inside the function. My snippet will have half of the computational complexity of dWinder's solution -- just one loop instead of two.
Code: (Demo) (or with compact())
$values = ["10100153", "2007", "350", "804082", "WW006", "WHT/NNY/OXGM", "35/38", "804082 WW00635/38", "0,00138857", "Champion 3pk Quarter Socks"];
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$keys = ["Value", "Number"];
var_export(
array_map(function(...$data) use ($keys) {
return array_combine($keys, $data);
}, $values, $numbers)
);
Output:
array (
0 =>
array (
'Value' => '10100153',
'Number' => 1,
),
1 =>
array (
'Value' => '2007',
'Number' => 2,
),
2 =>
array (
'Value' => '350',
'Number' => 3,
),
...you get the point
)
This question already has answers here:
How to Sum Columns of a Multi-Dimensional Array?
(4 answers)
Closed 5 months ago.
I have an arrays with dynamic name. My array could be more than 3, depends and array variable should be unique
$loopThrice = 3;
$getSum = 0;
$total = array();
$array0 = array(5, 10, 15, 20, 25, 30);
$array1 = array(1, 2, 3, 4, 5, 6);
$array2 = array(2, 6, 8, 10, 12, 14);
for($a=0; $a < $loopThrice; $a++){ // loop 3x to get unique array name
foreach (${'array'.$a} as $key => $value) { // $array0, $array1, $array2,
//Right here is my problem, I'm not sure if this the correct way to get the sum of $array0,1,2
//get the sum of array0,1,2 -- newarray(8, 18, 26, 34, 42, 50)
$getSum +=
//store newarray
array_push($total, $getSum);
}
}
I need to get an output like this:
Array (
[0] => 8
[1] => 18
[2] => 26
[3] => 34
[4] => 43
[5] => 50
)
Why aren't you using a multidimensional array?
$array = array(); // hungarian notation
$array[] = array(5, 10, 15, 20, 25, 30);
$array[] = array(1, 2, 3, 4, 5, 6);
$array[] = array(2, 6, 8, 10, 12, 14);
In this case you will have an array of arrays:
Array
(
[0] => Array
(
[0] => 5
[1] => 10
[2] => 15
[3] => 20
[4] => 25
[5] => 30
)
[1] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)
[2] => Array
(
[0] => 2
[1] => 6
[2] => 8
[3] => 10
[4] => 12
[5] => 14
)
)
You can go with nested for loops:
$sumArray = array();
$arrayCount = count($array);
$elementCount = 0;
foreach($array as $subarray)
{
$count = count($subarray);
$elementCount = $elementCount < $count ? $count : $elementCount;
}
for($i = 0; $i < $elementCount; $i++)
{
$sumArray[$i] = 0;
for($j = 0; $j < $arrayCount; $j++)
{
$sumArray[$i] += $array[$j][$i];
}
}
print_r($sumArray);
The output is
Array
(
[0] => 8
[1] => 18
[2] => 26
[3] => 34
[4] => 42
[5] => 50
)
Now, if you have a disproportioned sub-arrays (i.e. different count of elements in each sub-array), you will still get some sort of result, as missing elements will be assumed to be 0. So, with the input of:
$array = array(); // hungarian notation
$array[] = array(5, 10, 15, 20, 25);
$array[] = array(1, 2, 3, 4, 5, 6);
$array[] = array(2, 6, 8, 10);
You will still get the result:
Array
(
[0] => 8
[1] => 18
[2] => 26
[3] => 34
[4] => 30
[5] => 6
)
Well the multi array is the way to go, but you can still do it this way:
$loopThrice = 3;
$getSum = 0;
$total = array();
$array0 = array(5, 10, 15, 20, 25, 30);
$array1 = array(1, 2, 3, 4, 5, 6);
$array2 = array(2, 6, 8, 10, 12, 14);
// find which arrray has the most values
for($a=0; $a < $loopThrice; $a++){
$max_index = (count(${'array'.$a}) > $max_index ? count(${'array'.$a}) : $max_index);
}
for($i=0; $i < $max_index; $i++){
for($a=0; $a < $loopThrice; $a++){
$total[$i] += ${'array'.$a}[$i];
}
}
print_r($total);
// prints Array ( [0] => 8 [1] => 18 [2] => 26 [3] => 34 [4] => 42 [5] => 50 )
This should work for you:
$array0 = array(5, 10, 15, 20, 25, 30);
$array1 = array(1, 2, 3, 4, 5, 6);
$array2 = array(2, 6, 8, 10, 12, 14);
$var_prefix = 'array';
$arr_count = 0;
$max_fields = 0;
while(isset(${$var_prefix.$arr_count})) {
$data[] = ${$var_prefix.$arr_count};
if(count(${$var_prefix.$arr_count})>$max_fields) {
$max_fields = count(${$var_prefix.$arr_count});
};
$arr_count++;
}
for($i=0; $i<$max_fields; $i++) {
$result[$i] = array_sum(array_column($data, $i));
}
echo '<pre>';
print_r($result);
echo '</pre>';
die();
I don't know why you have individual array variables, but the process remains the same as if you declare a single array containing those arrays as rows in a multi-dimensional array.
Once you have a multi-dimensional array, the spread operator (...) will feed columns of data into array_map()'s custom function body -- where array_sum() can be called upon.
This task is effectively summing transposed data.
Code: (Demo)
var_export(
array_map(fn() => array_sum(func_get_args()), $array0, $array1, $array2)
);
Or:
var_export(
array_map(fn(...$cols) => array_sum($cols), $array0, $array1, $array2)
);
Output (from either approach):
array (
0 => 8,
1 => 18,
2 => 26,
3 => 34,
4 => 42,
5 => 50,
)
I have two arrays in PHP like this:
$array1 = array(array("1", "3", "4"), array("1", "4"));
$array2 = array(array("5", "4", "3", "2"), array("5", "3"));
Now I want to get all possible intersections of these two multidimensional arrays. Means I would get 4 arrays in total:
$array1[0] & $array2[0]
$array1[1] & $array2[0]
$array1[0] & $array2[1]
$array1[1] & $array2[1]
I can get the intersection from a onedimensional array using array_intersect(). But how can I get all possible intersections of multiple multidimensional arrays?
Here we create an array containing all combinations of arrays, so we can later take the intersections of these arrays.
Array combinations
First we need to create all possible combinations of arrays. Which is:
carray 1 * carray 2 * ... * carray n
"c" Just means the count() of the arrays
So in your specific example it would be:
carray 1 * carray 2 => 2 * 2 => 4 combinations
Now we need to get all these combinations and put them into an array. For this we start with an empty $combinations array. Then we loop through all combinations which we have in the array and merge the next array into it, until we have the desired length of the combination, in this case the amount of arrays which we have.
So as an example:
Array with the elements (Empty array is '[]'):
[
[[1, 3, 4], [1, 4]], //array 1
[[5, 4, 3, 2], [5, 3]], //array 2
]
1* combination array 2* new array //↓new combinations
↓ ↓ //↓for the next iteration
│
array NAN*:
Combinations:
- [] │ -> []
│
array 1: ┌──────────────────────────────────┘
│
Combinations: v
- [] + [1, 3, 4] │ -> [[1, 3, 4]]
- [] + [1, 4] │ -> [[1, 4]]
│
array 2: ┌──────────────────────────────────┘
│
Combinations: v
- [[1, 3, 4]] + [5, 4, 3, 2] │ -> [[1, 3, 4], [5, 4, 3, 2]]
- [[1, 3, 4]] + [5, 3] │ -> [[1, 3, 4], [5, 3]]
- [[1, 4]] + [5, 4, 3, 2] │ -> [[1, 4], [5, 4, 3, 2]]
- [[1, 4]] + [5, 3] │ -> [[1, 4], [5, 3]]
//↑ All combinations here
* NAN: not a number
So as you can see in the above example we now have all combinations with the length of the amount of all arrays which we have (4 combinations with a length of 2 elements).
The code to get the combinations as shown in the example above is:
//The for loop makes sure we get the desired length of each combination
//(The amount of arrays which we have. Here 2)
for ($count = 0, $length = count($data); $count < $length; $count++) {
$tmp = [];
foreach ($combinations as $v1) { //1* combinations array
foreach ($data[$count] as $v2) //2* new array
$tmp[] = array_merge($v1, [$v2]); //Creating new combinations
}
$combinations = $tmp; //Assigning the new combinations for the next iteration
}
Which in your specific example generates this array:
Array
(
[0] => Array //Combination 1
(
[0] => Array
(
[0] => 1
[1] => 3
[2] => 4
)
[1] => Array
(
[0] => 5
[1] => 4
[2] => 3
[3] => 2
)
)
[1] => Array //Combination 2
(
[0] => Array
(
[0] => 1
[1] => 3
[2] => 4
)
[1] => Array
(
[0] => 5
[1] => 3
)
)
[2] => Array //Combination 3
(
[0] => Array
(
[0] => 1
[1] => 4
)
[1] => Array
(
[0] => 5
[1] => 4
[2] => 3
[3] => 2
)
)
[3] => Array //Combination 4
(
[0] => Array
(
[0] => 1
[1] => 4
)
[1] => Array
(
[0] => 5
[1] => 3
)
)
)
Array intersection
Now that we have all combinations we can just go through the combinations array with array_map() and get the array_intersect() of each combination. And since we don't know from how many arrays we want the intersection, we just use call_user_func_array(), e.g.
$intersections = array_map(function($v){
//intersection of each combination, which we created
return call_user_func_array("array_intersect", $v);
}, $combinations);
Full code:
<?php
$array1 = [[1, 3, 4], [1, 4]];
$array2 = [[5, 4, 3, 2], [5, 3]];
function getIntersections($data = []) {
$combinations = [[]];
for ($count = 0, $length = count($data); $count < $length; $count++) {
$tmp = [];
foreach ($combinations as $v1) {
foreach ($data[$count] as $v2)
$tmp[] = array_merge($v1, [$v2]);
}
$combinations = $tmp;
}
$intersections = array_map(function($v){
return call_user_func_array("array_intersect", $v);
}, $combinations);
return $intersections;
}
$intersections = getIntersections([$array1, $array2]);
print_r($intersections);
?>
output:
Array
(
[0] => Array //Intersection of: [1, 3, 4] && [5, 4, 3, 2]
(
[1] => 3
[2] => 4
)
[1] => Array //Intersection of: [1, 3, 4] && [5, 3]
(
[1] => 3
)
[2] => Array //Intersection of: [1, 4] && [5, 4, 3, 2]
(
[1] => 4
)
[3] => Array //Intersection of: [1, 4] && [5, 3]
(
)
)
This foreach is solving my problem
$array1= array(array("1","3","4"),array("1","4"));
$array2= array(array("5","4","3","2"),array("5","3"));
$result = array();
echo "<pre>";
foreach($array1 as $array1)
{
foreach($array2 as $array3)
{
print_r($array3);
$result[] = array_intersect($array1,$array3);
}
}
print_r($result);
If You have better solution then plz improve it
In PHP, I have 2 multidimensional arrays. such as:
array 1:
[[1, 2, 3], [1, 2, 3]];
Array 2:
[[4, 5, 6], [7, 8, 9]];
I need to combine these two arrays.
I need the first array's subarray values to be the keys of resulting multidimensional's subarrays and the second array's subarray values to be the values of resulting multidimensional's subarray.
I need the output like this format:
array (
0 =>
array (
1 => 4,
2 => 5,
3 => 6,
),
1 =>
array (
1 => 7,
2 => 8,
3 => 9,
),
)
Try with:
$length = sizeof($arrayA);
$output = array();
for ( $i = 0; $i < $length; ++$i ) {
$output[] = array_combine($arrayA[$i], $arrayB[$i]);
}
This can be concisely accomplished by calling array_combine() while simultaneously iterating (mapping) the two equal-length arrays with equal-length subarrays.
Code: (Demo)
$arr1 = [[1, 2, 3], [1, 2, 3]];
$arr2 = [[4, 5, 6], [7, 8, 9]];
var_export(
array_map('array_combine', $arr1, $arr2)
);
Output:
array (
0 =>
array (
1 => 4,
2 => 5,
3 => 6,
),
1 =>
array (
1 => 7,
2 => 8,
3 => 9,
),
)