Reputation: 9
An array of values are provided in the order they should appear in columns. For example, the second value in the array should be displayed on a webpage beneath the first instead of on its right.
Task: Reorder the array so that the values are in the order they will be output in html. The data for the first row must be first in the output.
Example inputs:
$input = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
$cols = 2;
Example output:
[['A', 'E'], ['B','F'], ...]
Upvotes: 0
Views: 176
Reputation: 47894
The modern functional equivalent of @billyonecan's approach uses the spread operator to transpose the data after it has been "chunked" to the correct size. (Demo)
$input = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
$cols = 2;
var_export(
array_map(
null,
...array_chunk($input, ceil(count($input) / 2))
)
);
// [['A', 'E'], ['B', 'F'], ['C', 'G'], ['D', null]]
A classic loop alternative using a modulus calculation is also attractive because it doesn't generate the extra null
element in the final set when the division doesn't come out even: (Demo)
$input = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
$cols = 2;
$rows = ceil(count($input) / $cols);
$result = [];
foreach ($input as $i => $value) {
$result[$i % $rows][] = $value;
}
var_export($result);
// [['A', 'E'], ['B', 'F'], ['C', 'G'], ['D']]
On this related topic, to more simply chunk and transpose with a finite number of rows, use the following: (Demo)
$rows = 2;
var_export(
array_map(
null,
...array_chunk($input, $rows)
)
);
Upvotes: 0
Reputation: 20260
Use array_chunk()
to break the array up in to $cols
:
$chunks = array_chunk($array, ceil(count($array) / $cols));
Which would give you:
array(array('A', 'B', 'C', 'D'), array('E', 'F', 'G'));
Then combine the values from each array where the keys match.
array_unshift($chunks, null);
$chunks = call_user_func_array('array_map', $chunks);
// array(array('A', 'E'), array('B', 'F'), array('C', 'G'), array('D', NULL))
Upvotes: 1
Reputation: 3337
You need to count offset and then iterate over an array:
$input = array('A', 'B', 'C', 'D', 'E', 'F', 'G');
$cols = 2;
$itemsCount = count($input);
$offset = ceil($itemsCount/$cols);
$result = array();
for($i = 0; $i < $itemsCount; ++$i) {
if (isset($input[$i]) && isset($input[$i + $offset])) {
$result[] = array($input[$i], $input[$i + $offset]);
}
}
Upvotes: 0