Split array into chunks of alternating sizes - php

I have an array:
Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] => 4
[5] => 5
[6] => 6
[7] => 7
[8] => 8
[9] => 9
)
I want to split the array into alternating chunks. (size 2 then 3 then 2 then 3 etc)
Array
(
[0] => Array
(
[0] => 0
[1] => 1
[2] => 2
)
[1] => Array
(
[0] => 3
[1] => 4
)
[2] => Array
(
[0] => 5
[1] => 6
[2] => 7
)
[3] => Array
(
[0] => 8
[1] => 9
)
)

That should work:
$a = array(0 => 0,1 => 1,2 => 2,3 => 3,4 => 4, 5 => 5, 6 => 6,7 => 7,8 => 8,9 => 9);
$chunks = array();
$i=1;
while(count($a)){
$chunks[] = array_splice($a, 0,(2+($i%2)),array());
$i++;
}
echo "<pre>";
var_dump($chunks);

You can use array_splice for splitting the array, but you need to set conditions right? On what basis do you wanna split them?
And you can use array_merge to bring them back into an array of arrays.
In case of your current code, the code will be:
PHP Code
<?php
$array = array(0,1,2,3,4,5,6,7,8,9);
$final = array(
array_splice($array, 0, 3),
array_splice($array, 1, 2),
array_splice($array, 1, 2),
array_splice($array, 1, 2),
);
print_r($final);
?>
Output
Array
(
[0] => Array
(
[0] => 0
[1] => 1
[2] => 2
)
[1] => Array
(
[0] => 4
[1] => 5
)
[2] => Array
(
[0] => 6
[1] => 7
)
[3] => Array
(
[0] => 8
[1] => 9
)
)
Fiddle here: http://codepad.org/JzxcZ2Q1

Iterated calls of array_splice() seems like a great way to go. Here is a cleaner version of István Őri's answer. Subtracting from 5 removes the need to use the modulus operator.
Code: (Demo)
$array = range(1, 10);
$chunks = [];
$chunkSize = 3;
while ($array) {
$chunkSize = 5 - $chunkSize;
$chunks[] = array_splice($array, 0, $chunkSize);
}
var_export($chunks);
This snippet modifies $array as it iterates. array_splice() keeps removing elements from the front of the array. Eventually the array will become empty and the while() condition will fail -- breaking the loop.

You could use this, it isn't the most elegant, but it will just do the trick for you - and you can modify it nicely and adapt it to suit your purposes further:
<?php
$originalArray = array(0,1,2,3,4,5,6,7,8,9);
$counter=count($originalArray);
$isTwo=true;
$newArray=array();
$arrElement=0;
$i=0;
while($i<$counter)
{
if($isTwo)
{
$newArray[$arrElement]= array();
for($j=0; $j<2; $j++)
{
$newArray[$arrElement][$j]=$originalArray[$i+$j];
}
$i+=2;
$isTwo=false;
$arrElement++;
}
else
{
$newArray[$arrElement]= array();
for($j=0; $j<3; $j++)
{
$newArray[$arrElement][$j]=$originalArray[$i+$j];
}
$i+=3;
$isTwo=true;
$arrElement++;
}
}
var_dump($newArray);
?>
Output:
array(4) {
[0]=>
array(2) {
[0]=>
int(0)
[1]=>
int(1)
}
[1]=>
array(3) {
[0]=>
int(2)
[1]=>
int(3)
[2]=>
int(4)
}
[2]=>
array(2) {
[0]=>
int(5)
[1]=>
int(6)
}
[3]=>
array(3) {
[0]=>
int(7)
[1]=>
int(8)
[2]=>
int(9)
}
}

$tobechunked_arr = array(0,1,2,3,4,5,6,7,8,9);
$chunk_size_arr = array(3,2,3,2);
$j = 0;
foreach($chunk_size_arr as $key => $val)
{
for($i = 0; $i < $val; $i++)
{
$result_arr[$key][] = $tobechunked_arr[$j];
$j++;
}
}
echo "<pre>";
print_r($result_arr);

try this
<?php
$input_array = array('a', 'b', 'c', 'd', 'e');
print_r(array_chunk($input_array, 2));
print_r(array_chunk($input_array, 2, true));
?>
Update
<?php
$myArray = array("abc","def","ghi","jkl","mno","pqr","stu","vwx","yz");
$newArray = array_chunk($myArray, 2, false);
// Now process the multidimensional array made from array_chunk()
$i = 0;
foreach ($newArray as $inner_array) {
$i++;
echo "<h2>Chunk $i</h2>";
while (list($key, $value) = each($inner_array)) {
echo "$key: $value <br />";
}
}
?>
Output
Chunk 1
0: abc
1: def
Chunk 2
0: ghi
1: jkl
Chunk 3
0: mno
1: pqr
Chunk 4
0: stu
1: vwx
Chunk 5
0: yz

Related

How to count all values in a multidimensional array?

I have tried solutions to many similar questions, but they all seem to give me a count for each array. So I have the following array:
Array
(
[1] => Array
(
[0] => 1
[1] => 12
[2] => 2
)
[2] => Array
(
[0] => 1
[1] => 13
[2] => 3
)
[3] => Array
(
[0] => 1
[1] => 12
[2] => 2
)
[4] => Array
(
[0] => 1
)
[5] => Array
(
[0] => 1
)
)
I am trying to count the duplicates across all arrays. So the output should show:
Five 1's
Two 12's
One 13
Two 2's
At the moment I am trying:
foreach($data as $key => $row) {
print_r(array_count_values($row));
}
Which outputs the counts for each individual array
Array
(
[1] => 1
[12] => 1
[2] => 1
)
Array
(
[1] => 1
[13] => 1
[3] => 1
)
Array
(
[1] => 1
[12] => 1
[2] => 1
)
Array
(
[1] => 1
)
Array
(
[1] => 1
)
I have also tried this:
foreach ($data as $key => $row) {
$counts = array_count_values(array_column($data, $key));
var_dump($counts);
}
Which seems to miss a lot of information, like the count of the 1's
array(2) {
[12]=>
int(2)
[13]=>
int(1)
}
array(2) {
[2]=>
int(2)
[3]=>
int(1)
}
array(0) {
}
array(0) {
}
array(0) {
}
As a note, the initial array keys will not always be sequential, as this represents a row number. So this array may contain rows 1, 2, 5, 6, 7 etc.
How would I go about counting all duplicates together?
Since your array is not flattened, you will need to visit each value and increment unless you want to call merging functions.
Code: (Demo)
$array = [
1 => [1, 12, 2],
2 => [1, 13, 3],
3 => [1, 12, 2],
4 => [1],
5 => [1]
];
// make the generated value available outside of function scope
// \-------------------------------v--------------------------/
array_walk_recursive($array, function($v)use(&$output) { // visit each leafnode
if (isset($output[$v])) { // check if the key has occurred before
++$output[$v]; // increment
} else {
$output[$v] = 1; // declare as 1 on first occurrence
}
});
var_export($output);
Output:
array (
1 => 5,
12 => 2,
2 => 2,
13 => 1,
3 => 1,
)
Or, non-recursively:
foreach ($array as $row) {
foreach ($row as $v) {
if (isset($output[$v])) { // check if the key has occurred before
++$output[$v]; // increment
} else {
$output[$v] = 1; // declare as 1 on first occurrence
}
}
}
Or, a functional one-liner to flatten then count:
var_export(array_count_values(array_reduce($array, 'array_merge', array())));
Or, a functional one-liner with the splat operator to flatten then count:
var_export(array_count_values(array_merge(...$array)));
You can do this quite easily by using an accumulator array and iterating all the elements:
$result = [];
foreach ($data as $row) {
foreach($row as $value) {
$result[$value] = isset($result[$value]) ? $result[$value] + 1 : 1;
}
}
var_dump($result);
You can use call_user_func_array to merge all the individual arrays, and then array_count_values on that result:
$data = array
(array(1, 12, 2),
array(1, 13, 3),
array(1, 12, 2),
array(1),
array(1)
);
print_r(array_count_values(call_user_func_array('array_merge', $data)));
Output:
Array
(
[1] => 5
[12] => 2
[2] => 2
[13] => 1
[3] => 1
)

How set the array in php?

I have got this Array
Array ( [0] => 9314802498 [1] => 9314801890 [2] => MOSWAPELE ESTHER [3] => BENNETH )
I Want to retrieve like that Array
Array ( [0] => 9314802498 [1] => MOSWAPELE ESTHER [2] => 9314801890 [3] => BENNETH )
This can help -
$array = array ( 0 => 9314802498, 1 => 9314801890, 2 => 'MOSWAPELE ESTHER', 3 => 'BENNETH' );
$temp= array_chunk($array, count($array)/2);
$final = array();
foreach($temp[0] as $key => $val) {
$final[]= $val;
$final[]= !empty($temp[1][$key]) ? $temp[1][$key] : null;
}
var_dump($final);
Output
array(4) {
[0]=>
float(9314802498)
[1]=>
string(16) "MOSWAPELE ESTHER"
[2]=>
float(9314801890)
[3]=>
string(7) "BENNETH"
}
Assuming the count of numbers and names would be equal in that array. If not -
$temp= array_chunk($array, ceil(count($array)/2));
change the key
$arr = Array ( [0] => 9314802498 [1] => 9314801890 [2] => MOSWAPELE ESTHER [3] => BENNETH );
$arr[1] = 'MOSWAPELE ESTHER';
$arr[2] = '9314801890';
It will give you desired answer
Try replacing the key values like this:
$arr1 = array('9314802498', '9314801890', 'MOSWAPELE ESTHER', 'BENNETH');
$temp = $arr1[1];
$arr1[1] = $arr1[2];
$arr1[2] = $temp;
Try this code.
$arr = array(
0 => 9314802498,
1 => 9314801890,
2 => 'MOSWAPELE ESTHER',
3 => 'BENNETH'
);
$temp_val = $arr[1];
$arr[1] = $arr[2];
$arr[2] = $temp_val;
print_r($arr);
Output
Array ( [0] => 9314802498 [1] => MOSWAPELE ESTHER [2] => 9314801890 [3] => BENNETH )

Enhancing asort by order of keys

I am using asort to sort the numeric array. For e.g.
$arr = [0,1,1,2,1,2,2,3];
After running asort I am getting:
Array
(
[0] => 0
[4] => 1
[2] => 1
[1] => 1
[6] => 2
[3] => 2
[5] => 2
[7] => 3
)
But I am expecting to get it in this order:
Array
(
[0] => 0
[1] => 1
[2] => 1
[4] => 1
[3] => 2
[5] => 2
[6] => 2
[7] => 3
)
See the difference in order of the keys above.
First sort the array.
Then generate an array by flipping in a way so that the keys can be separated according to values. Sort the arrays with keys and merge them to an array. And the combine the keys with the sorted values.
$arr = [0,1,1,2,1,2,2,3];
asort($arr);
$sorted = $arr;
$flipped = $new_keys = array();
foreach($arr as $key => $val) {
$flipped[$val][] = $key; // Get the keys
}
foreach($flipped as $key => $val_array) {
asort($val_array); // Sort the keys
$new_keys = array_merge($new_keys, $val_array);
}
$final = array_combine($new_keys, $sorted); // Combine them again
var_dump($final);
Output
array(8) {
[0]=>
int(0)
[1]=>
int(1)
[2]=>
int(1)
[4]=>
int(1)
[3]=>
int(2)
[5]=>
int(2)
[6]=>
int(2)
[7]=>
int(3)
}
This should work for you:
First walk through each array value with array_walk() and change each value to an array containing the value and the key.
After this use uasort() to sort your array and if both values are the same you use the key to choose which one should be first.
At the end just use array_column() to transform your array back.
<?php
$arr = [0,1,1,2,1,2,2,3];
array_walk($arr, function(&$v, $k){
$v = ["value" => $v, "key" => $k];
});
uasort($arr, function($a, $b){
if($a["value"] == $b["value"]) {
if($a["key"] == $b["key"])
return 0;
return $a["key"] > $b["key"] ? 1 : -1;
}
return $a["value"] > $b["value"] ? 1 : -1;
});
$arr = array_column($arr, "value", "key");
print_r($arr);
?>
output:
Array
(
[0] => 0
[1] => 1
[2] => 1
[4] => 1
[3] => 2
[5] => 2
[6] => 2
[7] => 3
)

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);

Adding arrays in php

Arrays have been comprehensively covered but am still stumped about how to go around this. I have two arrays which i want to merge without overwriting duplicate keys i.e.
Array1
(
[0] => 0
[1] => 1
[2] => 1
[3] => 1
[4] => 1
[5] => 0
[6] => 0
)
+
Array2
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
[6] => 1
)
my ideal result is
Array1 + Array2
(
[0] => 0
[1] => 1
[2] => 1
[3] => 1
[4] => 1
[5] => 0
[6] => 1
)
How would i do this? I've tried using + but it gives the first array as the result
What you want to do is to map both arrays into single array, containing max value from two respective values, like that:
$array1 = array(0, 1, 1, 1, 1, 0, 0);
$array2 = array(0, 0, 0, 0, 0, 0, 1);
$result = array_map('max', $array1, $array2);
See the result here: http://ideone.com/clone/MN568
It looks like that:
array(7) {
[0]=>
int(0)
[1]=>
int(1)
[2]=>
int(1)
[3]=>
int(1)
[4]=>
int(1)
[5]=>
int(0)
[6]=>
int(1)
}
array_merge() does not overwrite duplicate elements that have numeric keys.
Given the arrays are of the same length:
function bitwise_or_arrays($arr1, $arr2) {
$result = array();
for ($i = 0; $i < count($arr1); $i++) {
$result[$i] = $arr1 | $arr2;
}
return $result;
}
If you are looking for the greater (nonzero) of the two arrays, you can iterate like so:
$array1 = array(1,0,0,1,1,1);
$array2 = array(0,0,1,0,0,1);
$newarr = array();
foreach ($array1 as $k => $v) {
$newarr[$k] = max($array1[$k], $array2[$k]);
}
print_r($newarr);
Array
(
[0] => 1
[1] => 0
[2] => 1
[3] => 1
[4] => 1
[5] => 1
)
If what you need is to add the values, use:
$newarr = array();
foreach ($array1 as $k => $v) {
$newarr[$k] = $array1[$k] + $array2[$k];
}
Just for fun (although in your case with 0 and 1 values it works :)
$array1 = array(0, 1, 1, 1, 1, 0, 0);
$array2 = array(0, 0, 0, 0, 0, 0, 1);
$str1 = implode('', $array1);
$str2 = implode('', $array2);
$result = str_split($str1 | $str2);
Sorry for this variant, I know it's crazy, but just couldn't not to post it. Arrays look like bit masks 0111100 and 0000001. So just using bitwise | operator.
So result:
Array
(
[0] => 0
[1] => 1
[2] => 1
[3] => 1
[4] => 1
[5] => 0
[6] => 1
)
If what your looking is to combine them use array_combine().
$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);
print_r($c);
//*output:
array(
[green] => avocado
[red] => apple
[yellow] => banana
)
here's how to merge array:
$beginning = 'foo';
$end = array(1 => 'bar');
$result = array_merge((array)$beginning, (array)$end);
print_r($result);
//output:
Array(
[0] => foo
[1] => bar
)
heres how to add values
$a = array(0=>1, 1=>2, 2=>3, 3=>4);
$b = array(0=>5, 1=>6, 2=>7, 3=>8);
$c = $a[0] += $b[0];
print_r($c);//output: 6
im not a guru on php but i hope this helps you even just abit.
Just for the fun of it:
$array1 = array(0,1,1,1,1,0,0);
$array2 = array(0,0,0,0,0,0,1);
$array3 = str_split(decbin(bindec(implode('',$array1)) | bindec(implode('',$array2))));
var_dump($array3);
Unfortunately it trims leading zeroes
Using
$array3 = str_split(str_pad(decbin(bindec(implode('',$array1)) | bindec(implode('',$array2))),count($array1),'0',STR_PAD_LEFT));
will restore leading zeroes, but doesn't feel as clean

Categories