How to divide two arrays equally in PHP? - php

I'm trying to divide arrays equally from two sets of arrays
For example:
$arr1 = [a,b,c,d,e];
$arr2 = [1,2,3,4,5,6,7,8,9,10,11,12,13];
What I have tried:
$arr1 = [a,b,c,d,e];
$arr2 = [1,2,3,4,5,6,7,8,9,10,11,12,13];
$arrRes = [];
$key = 0;
for($i=0;$i<count($arr1);$i++){
$arrRes[$arr1[$key]][] = $arr2[$i];
$key++;
}
$key2 = 0;
for($k=0;$k<count($arr1);$k++){
$arrRes[$arr1[$key2]][] = $arr2[$key];
$key++;
$key2++;
if ($key == count($arr2)) {
break;
}
}
I expect to get the output:
[
"a" => [1,6,11],
"b" => [2,7,12],
"c" => [3,8,13],
"d" => [4,9],
"e" => [5,10]
]
but the actual output I get is :
[
"a" => [1,6],
"b" => [2,7],
"c" => [3,8],
"d" => [4,9],
"e" => [5,10]
]

Another way with just using 1 loop (comments in code)...
$arr1 = ['a','b','c','d','e'];
$arr2 = [1,2,3,4,5,6,7,8,9,10,11,12,13];
// Create output array from the keys in $arr1 and an empty array
$arrRes = array_fill_keys($arr1, []);
$outElements = count($arr1);
// Loop over numbers
foreach ( $arr2 as $item => $value ) {
// Add the value to the index based on the current
// index and the corresponding array in $arr1.
// Using $item%$outElements rolls the index over
$arrRes[$arr1[$item%$outElements]][] = $value;
}
print_r($arrRes);
Output...
Array
(
[a] => Array
(
[0] => 1
[1] => 6
[2] => 11
)
[b] => Array
(
[0] => 2
[1] => 7
[2] => 12
)
[c] => Array
(
[0] => 3
[1] => 8
[2] => 13
)
[d] => Array
(
[0] => 4
[1] => 9
)
[e] => Array
(
[0] => 5
[1] => 10
)
)

The code snippet bellow does exactly what you want. It calculates the max length of the resulting inner arrays (which in your case is 13/5+1=3) by dividing the length of the 2nd array with the length of the 1st array. Then, for each element in the 1st array, it goes from 0 to the max length and adds the element from the 2nd array at that position to the resulting array. In the case that the position is out of bounds, the inner for loop is exited.
$arr1 = ['a', 'b', 'c', 'd', 'e'];
$arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
$arrRes = [];
// create an empty result array of arrays
foreach($arr1 as $key){
// the keys are the values from the 1st array
$arrRes[$key] = [];
}
$maxLength = intval(count($arr2) / count($arr1)) + 1;
for($i = 0; $i < count($arr1); ++$i) {
for($j = 0; $j < $maxLength; ++$j) {
$pos = $j * count($arr1) + $i;
if($pos >= count($arr2)) {
break;
}
$arrRes[$arr1[$i]][] = $arr2[$pos];
}
}
The above code produces:
[
"a" => [1,6,11],
"b" => [2,7,12],
"c" => [3,8,13],
"d" => [4,9],
"e" => [5,10]
]
And if you want a result like this:
[
"a" => [1,2,3],
"b" => [4,5,6],
"c" => [7,8,9],
"d" => [10,11],
"e" => [12,13]
]
... then this code will do this (the main difference is in getting the position and determining when to break the inner loop):
$arr1 = ['a', 'b', 'c', 'd', 'e'];
$arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
$arrRes = [];
foreach($arr1 as $key){
$arrRes[$key] = [];
}
$maxLength = intval(count($arr2) / count($arr1)) + 1;
$pos = 0;
for($i = 0; $i < count($arr1); ++$i) {
$arraysLeftAfter = count($arr1) - $i - 1;
for($j = 0; $j < $maxLength && $pos < count($arr2); ++$j) {
if($arraysLeftAfter > 0) {
$elCountAfter = count($arr2) - $pos - 1;
$myLengthAfter = ($j + 1);
$maxLengthAfter = floor(($elCountAfter / $arraysLeftAfter) + 1);
if($myLengthAfter > $maxLengthAfter) {
break;
}
}
$arrRes[$arr1[$i]][] = $arr2[$pos++];
}
}

A different approach:
$arr1 = ['a','b','c','d','e'];
$arr2 = [1,2,3,4,5,6,7,8,9,10,11,12,13];
$i =0;
$res = array_fill_keys($arr1, []);
while(isset($arr2[$i])){
foreach($res as $k=>&$v){
if(!isset($arr2[$i])) break;
$v[] = $arr2[$i];
$i++;
}
}
print_r($res);
Result:
Array
(
[a] => Array
(
[0] => 1
[1] => 6
[2] => 11
)
[b] => Array
(
[0] => 2
[1] => 7
[2] => 12
)
[c] => Array
(
[0] => 3
[1] => 8
[2] => 13
)
[d] => Array
(
[0] => 4
[1] => 9
)
[e] => Array
(
[0] => 5
[1] => 10
)
)

Related

PHP Array Swap in dynamic input

I have two dynamic arrays of integer, one thing that I wanna do is swap value inside my array-based on input.
For example my two arrays:
$myArray_a =
Array
(
[0] => 21306000
[1] => 50627412
[2] => 2560227681
[3] => 2796924085
[4] => 0
[5] => 0
)
$myArray_b =
Array
(
[0] => 505909732
[1] => 400831144
[2] => 2693575413
[3] => 3072271817
[4] => 5277000763
[5] => 4944000763
)
And my expected output was when the input = 3, array B index number 4 and 5 swap to array A in the same index.
$output =
Array
(
[0] => 21306000
[1] => 50627412
[2] => 2560227681
[3] => 2796924085
[4] => 5277000763
[5] => 4944000763
)
I want to switch, is there an easy way to do this? Or will it require a loop + creating a new array?
Provided your are using an numeric index, you could leverage array_slice
This will create an array with the first four entries, then append the second array skipping existing keys.
$count = 4; // which is 3 + 1
$a = [21306000,50627412,2560227681,2796924085,0,0];
$b = [505909732,400831144,2693575413,3072271817,5277000763,4944000763];
$output = array_slice( $a, 0, $count ) + $b;
//Array
//(
// [0] => 21306000
// [1] => 50627412
// [2] => 2560227681
// [3] => 2796924085
// [4] => 5277000763
// [5] => 4944000763
//)
You can do it with,
$index = 3;
$result = $B;
for($i = 0; $i<= $index; $i++){
$result[$i] = $A[$i];
}
You can use foreach
foreach($myArray_a as $k => &$v){
empty($v) && isset($myArray_b[$k]) ? ($v = $myArray_b[$k]) : '';
}
DEMO :- https://3v4l.org/nRj68
<?php
$a = [2,3,4,5,0,0];
$b = [20,30,40,50,60,70];
$counter = 0;
$out = array_map(function($m, $n ) use (&$counter)
{
return $counter++>3 ? $n : $m;
}, $a, $b);
var_export($out);
Output:
array (
0 => 2,
1 => 3,
2 => 4,
3 => 5,
4 => 60,
5 => 70,
)

Fill gaps in new array based on different lengths arrays

I am trying to create one array out of the two. Two arrays may be different lengths therefore the combine result should accommodate that and fill gaps with null.
My understanding is to first find a bigger array and loop over that, fill the gaps in the smaller array, and once that is done, merge it.
This is what I have done so far, but it feels very clunky, to the point I am starting to think - there must be a better way - less loops and maybe use some of the php array helpers methods ?
<?php
$result_keys = [];
$result_data = [];
$bigger = null;
$smaller = null;
$array1 = [
[
'dog' => 2,
'cat' => 3,
],
[
'dog' => 4,
'cat' => 2,
],
[
'dog' => 2,
'cat' => 3
]
];
$array2 = [
[
'bird' => 7,
],
[
'bird' => 5
]
];
// find which array is bigger
if (count($array1) >= count($array2)) {
$bigger = $array1;
$smaller = $array2;
} else {
$bigger = $array2;
$smaller = $array1;
};
// loop over bigger array
foreach ($bigger as $i => $record) {
foreach ($record as $key => $value) {
if ($i === 0) {
$result_keys[] = $key;
};
$result_data[$i][] = $value;
}
// fill gaps in smaller array
if (!isset($smaller[$i])) {
foreach ($smaller[$i-1] as $key => $value) {
$smaller[$i][$key] = null;
}
}
};
// loop over smaller array
foreach ($smaller as $i => $record) {
foreach ($record as $key => $value) {
if ($i === 0) {
$result_keys[] = $key;
};
$result_data[$i][] = $value;
}
};
var_dump($result_keys);
var_dump($result_data);
// // expected result
// $result_keys = ['dog', 'cat', 'bird'];
// $result_data = [
// [2,3,7],
// [4,2,5],
// [2,3,null]
// ];
My solution to your problem:
$array1 = [
[
'dog' => 2,
'cat' => 3,
],
[
'dog' => 4,
'cat' => 2,
],
[
'dog' => 2,
'cat' => 3
]
];
$array2 = [
[
'bird' => 7,
],
[
'bird' => 5
]
];
// get the number of values of the biggest array
$count = $count = count($array1) >= count($array2) ? count($array1) : count($array2);
$values = [];
$keys = [];
for ($i = 0; $i < $count; $i++) {
$a1 = $array1[$i] ?? [];
$a2 = $array2[$i] ?? [];
$keys = array_unique(array_merge($keys, array_keys($a1), array_keys($a2)));
$values[] = array_values(array_merge(array_fill_keys($keys, null), $a1, $a2));
}
print_r($keys);
print_r($values);
Results (test here):
Array
(
[0] => dog
[1] => cat
[2] => bird
)
Array
(
[0] => Array
(
[0] => 2
[1] => 3
[2] => 7
)
[1] => Array
(
[0] => 4
[1] => 2
[2] => 5
)
[2] => Array
(
[0] => 2
[1] => 3
[2] =>
)
)

How to group items in array by summary each item

<?php
$quantity = array(1,2,3,4,5,6,7,8,9,10,11,12,1,14,2,16);
// Create a new array
$output_array = array();
$sum_quantity = 0;
$i = 0;
foreach ($quantity as $value) {
if($sum_quantity >= 35) {
$output_array[$i][] = $value;
}
$sum_quantity = $sum_quantity + $value;
}
print_r($output_array);
When summmary each item >= 35 will auto create child array
array(
[0] => array(1, 2, 3, 4, 5, 6, 7),
[1] => array(8, 9, 10),
[2] => array(11, 12, 1),
[3] => array(14, 2, 16)
)
$quantity = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 14, 2, 16);
// Create a new array
$output_array = array();
$current_array = array();
$current_sum = 0;
foreach ($quantity as $value) {
$current_sum += $value;
if ($current_sum >= 35) {
$output_array[] = $current_array;
$current_array = array();
$current_sum = $value;
}
$current_array[] = $value;
}
$output_array[] = $current_array;
print_r($output_array);
// Output:
// Array
// (
// [0] => Array
// (
// [0] => 1
// [1] => 2
// [2] => 3
// [3] => 4
// [4] => 5
// [5] => 6
// [6] => 7
// )
// [1] => Array
// (
// [0] => 8
// [1] => 9
// [2] => 10
// )
// [2] => Array
// (
// [0] => 11
// [1] => 12
// [2] => 1
// )
// [3] => Array
// (
// [0] => 14
// [1] => 2
// [2] => 16
// )
// )
I see,maybe your desired answer is as follows,
$quantity = array(1,2,3,4,5,6,7,8,9,10,11,12,1,14,2,16);
// Create a new array
$output_array = array();
$sum_quantity = 0;
$i = 0;
for each($quantity as $value) {
$sum_quantity += $value;
if($sum_quantity >= 35) {
$i++;
$output_array[$i][] = $value;
$sum_quantity = $value;
}else{
$output_array[$i][] = $value;
}
}
print_r($output_array);
I have tried test,It's ok.

creating dimensional array with 2 single array

i have 2 arrays and i want 2 create 2D array for create mysql record
Array
(
[0] => a
[1] => b
[2] => c
)
Array
(
[0] => 1
[1] => 2
[2] => 3
)
i want 2 merge them into 2 dimensional array like this
Array
(
[0] => Array
(
[designation_id] => 1
[judge_name] => a
)
[1] => Array
(
[designation_id] => 2
[judge_name] => b
)
[2] => Array
(
[designation_id] => 3
[judge_name] => c
)
)
i use array_merge_recursive and it generates result like this
Array
(
[0] => a
[1] => b
[2] => c
[3] => 1
[4] => 2
[5] => 3
)
Assuming there will always be the same amount of values in $array1 as there are in $array2..
$array1 = Array("a","b","c");
$array2 = Array(1,2,3);
$newArray = Array();
foreach($array1 as $key => $arr1Val){
$newArray[$key]['designation_id'] = $array2[$key];
$newArray[$key]['judge_name'] = $array1[$key];
}
Of course, you will have to alter $array1 and $array2 to your needs, but you understand the basic idea. Check it here.
Assuming $array1 is the judge_name and $array2 is the designation_id
$newArray = array();
for($i=0; $i<count($array1); $i++)
{
$newArray[] = array(
'designation_id' => $array2[$i],
'judge_name' => $array1[$i]
);
}
Codepad Demo
Outputs
Array
(
[0] => Array
(
[designation_id] => 1
[judge_name] => a
)
[1] => Array
(
[designation_id] => 2
[judge_name] => b
)
[2] => Array
(
[designation_id] => 3
[judge_name] => c
)
)
simple as hell
$array1 = array('a', 'b', 'c');
$array2 = array(1,2,3);
$merged = array();
foreach($array1 as $key => $value)
{
$merged[$key] = array(
'judge_name' => $value,
'designation_id' => array_key_exists($key, $array2) ? $array2[$key] : null
);
}
Assuming that both arrays are of same size
$length = count($array1);
$finalArray = array();
for ($i = 0; $i < $length; $i++) {
$temp = array();
$temp['designation_id'] = $array1[$i];
$temp['judge_name'] = $array2[$i];
$finalArray[$i] = $temp;
}
$a = array('a', 'b', 'c');
$b = array(1,2,3);
$output = array_map(function($i, $j){
return array(
'judge_name' => $j,
'designation_id' => $i
);
}, $a, $b);
var_dump($output);
Outputs
array(3) {
[0]=>
array(2) {
["judge_name"]=>
int(1)
["designation_id"]=>
string(1) "a"
}
[1]=>
array(2) {
["judge_name"]=>
int(2)
["designation_id"]=>
string(1) "b"
}
[2]=>
array(2) {
["judge_name"]=>
int(3)
["designation_id"]=>
string(1) "c"
}
}
If you have PHP >= 5.3 you could use MultipleIterator for that purpose:
$designations = array(1, 2, 3);
$judges = array('a', 'b', 'c');
$mt = new MultipleIterator(MultipleIterator::MIT_KEYS_ASSOC);
$mt->attachIterator(new ArrayIterator($designations), "designation_id");
$mt->attachIterator(new ArrayIterator($judges), "judge_name");
$final = iterator_to_array($mt, false);
print_r($final);
Demo
It iterates over multiple arrays, taking a value from each array at every iterator; you can assign a key for each array that will be used to form a single array item.
Afterwards you convert the results into an array using iterator_to_array().
$new1=array("a","b","c");
$new2=array("1","2","3");
$req=array();
$d=0;
foreach($new1 as $value1)
{
foreach($new2 as $value2)
{
$req[$d]["designation_id"]=$value1;
$req[$d]["judge_name"]=$value2;
$d++;
}
}
echo "<pre>";
print_r($req);

Reading sorted array

Why $val is Array(1), but not the numeric value? I expected that $selected as $k => $val should return each line from the array $selected. Thus, $k must be a numeric key (it is) and $val must be corresponding numeric value (but it's an array instead of simple integer).
So, how do I correctly save sorted keys and values in array $ind and $ranks?
<?php
$selected = array();
for ($i=0; $i<5; $i++) {
$selected[] = array($i => rand(0,5));
}
arsort($selected);
$ind = array();
$rank = array();
foreach($selected as $k => $val) {
$ind[] = $k;
$rank[] = $val;
}
?>
UPDATE:
For incstance, this code..
for ($i=0; $i<5; $i++) {
$selected[$i] = rand(0,5);
}
provided the array:
[0] => 5, [1] => 3, [2] => 2, [3] => 5, [4] => 3
Once I sorted it, initial keys are deleted, right? How can I find initial keys [0]-[4] of randomly generated values after sorting the array?
I think your likely solution is to change
$selected[] = array($i => rand(0,5));
to
$selected[] = rand(0,5);
Doing so will yield $ind and $rank like this:
Array
(
[0] => 0
[1] => 3
[2] => 2
[3] => 4
[4] => 1
)
Array
(
[0] => 4
[1] => 3
[2] => 1
[3] => 0
[4] => 0
)
The best way to do what you want, is to just use the resultant array, for example:
$selected
Array
(
[1] => 5
[2] => 5
[4] => 4
[0] => 2
[3] => 1
)
I think this is what you need
for ($i=0; $i<5; $i++) {
$selected[$i] = rand(0,5);
}
Your array structure will look like this:
array(
0 => array(0 => 1),
1 => array(1 => 4),
...
)
because you're assigning an array here:
$selected[] = array($i => rand(0,5));
You just want this instead:
$selected[] = rand(0,5);
Hi I am not pretty much sure what you are trying to do but following code is creating an array of arrays.
$selected = array();
for ($i=0; $i<5; $i++) {
$selected[] = array($i => rand(0,5));
}
So $val will be an array. You can try following code:
$selected = array();
for ($i=0; $i<5; $i++) {
$selected[] = rand(0,5);
}
Thanks

Categories