There is an array containing K elements. What's the best way to get chunks of N < K items from this array?
Example input:
$x = [1,2,3,4,5,6,7,8,9,10]; // K = 10
Desired result, when N = 3;
$x1 = [1,2,3];
$x2 = [4,5,6];
$x3 = [7,8,9];
$x4 = [10];
Obviously, there is no need to store the result in variables. As long as it's possible to process it by foreach (or any other iteration logic), it should be fine.
The problem with array_slice is that it does not remove the N-slice from the beginning of the array. The problem with array_shift is that it does not support shifting more than 1 item at once. Is there anything more elegant than iterating over array_shift?
array_chunk is what you need.
<?php
$x = [1,2,3,4,5,6,7,8,9,10];
print_r(array_chunk($x,3));
OUTPUT :
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[0] => 4
[1] => 5
[2] => 6
)
[2] => Array
(
[0] => 7
[1] => 8
[2] => 9
)
[3] => Array
(
[0] => 10
)
)
Look into array_chunk -> http://www.w3schools.com/php/func_array_chunk.asp
$x = [1,2,3,4,5,6,7,8,9,10];
print_r(array_chunk($x,3,true));
or you could do it this way -
$x = [1,2,3,4,5,6,7,8,9,10];
$chunks = array();
while(count($x)){
$chunks[] = array_splice($x, 0,3,array());
$i++;
}
Could someone tell me which method would be more efficient?
array_chunk function is used to create sub arrays of equal size.
E.g.
$a=array_chunk($array,3);
Related
I am trying to split array data into multiple arrays based on change in data value at known position (column).
$input = array(
array(1,2,3),
array(4,5,3),
array(7,8,4),
array(9,10,4),
array(11,12,4)
);
Here column 3 changes values from 3 to 4
and expected result is to have 2 arrays
$out1 = array(array(1,2,3),array(4,5,3));
$out2 = array(array(7,8,4), array(9,10,4), array(11,12,4));
since number of rows are variable, cannot use array_chunk
since column 3 values are variable, cannot use array_filter
number of output arrays are also variable.
trying splice but failing...
You can use array_reduce to make new array, where index will be equal to last numbers in items
$new = array_reduce($input, function($c, $x) { $c[$x[2]][] = $x; return $c; }, [] );
$out1 = $new[3];
$out2 = $new[4];
demo
But if array is not sorted and you want to split at points of changing that number, the code can be
$i = -1;
$last = null;
$new = [];
foreach($input as $x) {
if ($x[2] != $last) {
$i++;
$last = $x[2];
}
$new[$i][] = $x;
}
demo
You can use split index with index of array,
$out1 = $out2 = [];
$splitIndex = 2;
foreach($input as $k => $v){
if($k < $splitIndex){
$out1[] = $v;
}else{
$out2[] = $v;
}
}
print_r($out1);
print_r($out2);
Working demo
Output:-
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[0] => 4
[1] => 5
[2] => 3
)
)
Array
(
[0] => Array
(
[0] => 7
[1] => 8
[2] => 4
)
[1] => Array
(
[0] => 9
[1] => 10
[2] => 4
)
[2] => Array
(
[0] => 11
[1] => 12
[2] => 4
)
)
I have a multidimensional array. I want to get array element which value is greater than 2 and less than 17. My Array is given below:
Array
(
[4] => Array
(
[0] => 17
[1] => 15
[2] => 12
)
[5] => Array
(
[0] => 16
)
[2] => Array
(
[0] => 3
[1] => 1
)
[1] => Array
(
[0] => 2
)
)
I want output like below:
Array
(
[4] => Array
(
[0] => 17
[1] => 15
[2] => 12
)
[5] => Array
(
[0] => 16
)
[2] => Array
(
[0] => 3
[1] => 1
)
)
Please help me how can I do it easy & fast method.
You can use a nested array filter.
$result = array_filter($outer_array, function($inner_array) {
return array_filter($inner_array, function($number) {
return $number > 2 && $number < 17;
});
});
Then inner array filter will result in an empty array being passed to the outer array filter if no values are found in the specified range. The empty array will evaluate to false in the outer filter callback, eliminating that array from the result.
Demo at 3v4l.org.
Generally, we want you to show what you have tried before we'll write code for you, but this one's on the house. For future reference, include some code snippets along with your question to avoid getting downvoted.
$output = array();
for($i = 0; $i < count($arr); $i++)
{
$use = false;
for($j = 0; $j < count($arr[$i]); $j++)
{
if($arr[$i][$j] > 2 and $arr[$i][$j] < 17)
{
$use = true;
break;
}
}
if($use)
$output[] = $arr[$i];
}
return $output;
This question already has answers here:
Transpose 2d array, join second level with commas, and join first level with pipes
(5 answers)
Closed 7 months ago.
I have an array with arrays in it representing values in a database.
There are over 100 columns in the db table so the actual count is much higher than this example below of 6 values, the sub-array (Array within the array) index 0-5.
The columns are in each index of the sub-array and the rows are in each index of the main array.
Here is my main array with sub-arrays:
Array
(
[0] => Array
(
[0] => N
[1] => N
[2] => Y
[3] => Y
[4] => Y
[5] => Y
)
[1] => Array
(
[0] => N
[1] => N
[2] => Y
[3] => Y
[4] => N
[5] => Y
)
[2] => Array
(
[0] => N
[1] => N
[2] => Y
[3] => Y
[4] => N
[5] => Y
)
[3] => Array
(
[0] => Y
[1] => Y
[2] => Y
[3] => Y
[4] => Y
[5] => Y
)
What I need to do is concat all the values of each sub index into one array like this:
Array
(
[0] => N,N,N,Y
[1] => N,N,N,Y
[2] => Y,Y,Y,Y
[3] => Y,Y,Y,Y
[4] => Y,N,N,Y
[5] => Y,Y,Y,Y
)
There will always be the same number of columns (sub index) but there will be different amounts of rows (index).
The idea is get the data by column, you're in luck, there's a built in function for that. Its array_column.
So first, get the number of columns and simply use a for loop for that. Then just use implode and assign it inside a new container:
$new = array(); // container
$count = count($arr[0]); // get the number of colums
for ($i = 0; $i < $count; $i++) {
// get the data by column number ($i), then implode and push inside
$new[] = implode(',', array_column($arr, $i));
}
Here's a sample output
Avoid using explicit loops like for and while. Use array_map (it can take the variable mumber of arrays to traverse):
$result = array_map(function (...$column) {
return implode(',', $column);
}, ...$array);
Here is the demo.
By the way, in linear algebra this is called transpose of the matrix.
From PHP7.4 and higher, the same technique can be written as: (Demo)
var_export(
array_map(
fn() => implode(',', func_get_args()),
...$array
)
);
Or: (Demo)
var_export(
array_map(
fn(...$column) => implode(',', $column),
...$array
)
);
I assume that you have defined $column as the total number of column in your db table. Use array_column to get the value according to the column key.
$result = array();
for ($i = 0; $i < $column; $i++) {
$res = array_column($arr, $i);
$result[] = implode(",", $res);
}
For more information about array_column function, check this link.
Oh, just to let you know that array_column function only works for PHP 5.5 and higher.
check if this is what you want
$arr = array(//your array);
$newArr = array(); //data wil lbe saved here
foreach($arr as $arr_one){
$string = "";
foreach($arr_one as $subArr){
$string.=$subArr.",";
}
array_push($newArr,rtrim($string,','));
}
var_dump($newArr);
This question already has answers here:
Finding cartesian product with PHP associative arrays
(10 answers)
Closed 7 years ago.
Initially, I am afraid, that I do not find a better title for this question.
I have a two dimensional array that looks like this, for example:
[0] => Array
(
[0] => 10,00
)
[1] => Array
(
[0] => 3
[1] => 4
)
[2] => Array
(
[0] => true
[1] => false
)
i'd like now to convert/parse this into a two dimensional array that looks like this:
[0] => Array
(
[0] => 10,00
[1] => 3
[2] => true
)
[1] => Array
(
[0] => 10,00
[1] => 4
[2] => true
)
[2] => Array
(
[0] => 10,00
[1] => 3
[2] => false
)
[3] => Array
(
[0] => 10,00
[1] => 4
[2] => false
)
i hope you see, that the result should provide all sort of possible combinations. indeed, the length of the first array can differ.
i'd be interested in how to solve this algorithmically, but at the moment i have no idea.
i am not sure, if this is as easy as it looks like. thank you in advance.
I imagine this could be refined, but it should do the trick:
<?php
$arrStart = array(
array('10,00'),
array(3, 4),
array('true', 'false')
);
$arrPositions = array();
$arrResult = array();
//get a starting position set for each sub array
for ($i = 0; $i < count($arrStart); $i++)
$arrPositions[] = 0;
//repeat until we've run out of items in $arrStart[0]
while (array_key_exists($arrPositions[0], $arrStart[0])) {
$arrTemp = array();
$blSuccess = true;
//go through each of the first array levels
for ($i = 0; $i < count($arrStart); $i++) {
//is there a item in the position we want in the current array?
if (array_key_exists($arrPositions[$i], $arrStart[$i])) {
//add that item to our temp array
$arrTemp[] = $arrStart[$i][$arrPositions[$i]];
} else {
//reset this position, and raise the one to the left
$arrPositions[$i] = 0;
$arrPositions[$i - 1]++;
$blSuccess = false;
}
}
//this one failed due to there not being an item where we wanted, skip to next go
if (!$blSuccess) continue;
//successfully adding nex line, increase the right hand count for the next one
$arrPositions[count($arrStart) - 1]++;
//add our latest temp array to the result
$arrResult[] = $arrTemp;
}
print_r($arrResult);
?>
I have 2 arrays that I need to combine or merge together. I am at a bit of a loss as to how to achieve this.
So the first array looks like this:
$arr1 =
Array (
[0] => Array
(
[id] => 7
[round] => 1
)
[1] => Array
(
[id] => 11
[round] => 2
)
....
And the second array looks like this:
$arr2 =
Array (
[round_1] => 21
[round_2] => 32
....
And I need the result to end up like this:
$result =
Array (
[0] => Array
(
[id] => 7
[round] => 1
[disp] => 21
)
[1] => Array
(
[id] => 11
[round] => 2
[disp] => 32
)
...... etc etc
Any ideas on where to get started for this??
Thanks
$i = 1; // Counter
$result = $arr1; // Copy $arr1 to preserve it. (if necessary)
foreach ($result as $x){
$x['disp'] = $arr2['round_' . $i];
$i ++;
}
This will iterate through Array1 setting a value for 'disp' in each sub array. This value will be pulled from Array2 and the round number would be incremented by a basic counter.
You could equally use a standard for loop for this too.
$result = $arr1; // Copy $arr1 to preserve it. (if necessary)
for($i = 0; $i < count($result); $i++){
$result[$i]['disp'] = $arr2['round_' . ($i + 1)];
}
Just make sure you do "$i + 1" when calling the value from Array2 because that doesn't seem to be 0 indexed.