I have an array which can have several items in it, e.g:
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
etc
I need the quickest way to restructure this array so that it has at most X items. So if I say that X is 3, the resulting array must be:
Item 1 , Item 2
Item 3, Item 4
Item 5, Item 6
etc
or if it has 7 items, it would be:
Item 1 , Item 2, Item 3,
Item 4, Item 5,
Item 6, Item 7
What's the easiest way to do this?
I started with this, but it seems like there really must be an easier way:
foreach ($addressParts as $part)
{
if (empty($part)) continue;
if (empty($addressLines[$count])) $addressLines[$count] = '';
$addressLines[$count] .= $part;
$count++;
if ($count > 2) $count = 0;
}
Also, this won't work, because you will end up with this:
item 1, item 4, item 7
item 2, item 5
item 3, item 6
... which is wrong. Any thoughts?
UPDATE
If I start with:
Array
(
[0] => item 1
[1] => item 2
[2] => item 3
[3] => item 4
[4] => item 5
[5] => item 6
[6] => item 7
)
I want to end with:
Array
(
[0] => item 1, item 2, item 3
[1] => item 4, item 5
[2] => item 6, item 7
)
Make sense?
Arrays can either hold primitive values or object values. An ArrayList can only hold object values. You must decide the size of the array when it is constructed. You can't change the size of the array after it's constructed.
Arrays can be restructured in four ways: Splitting a one-dimensional array into multiple one-dimension arrays. Folding a one-dimensional array into a multidimensional array. Flattening a multidimensional array into a one-dimensional array.
No problem—you can modify the values in arrays as easily as other variables. One way is to access an element in an array simply by referring to it by index.
This function combines elements to a new array as per your example. It handles any number of input elements.
function ReduceArray($input, $length) {
$frac = $length / count($input);
$frac = $frac + 0.0001; // Offset for float calculations
$index = 0.0;
// Copy the elements, rolling over on $index
$temp = array();
foreach ($input as $part) {
$i= floor($index);
if (!isset($temp[$i])) {
$temp[$i] = array($part);
} else {
$temp[$i][] = $part;
}
$index += $frac;
}
// Combine the sub arrays
$output = array();
foreach ($temp as $line) {
$output[] = implode(', ', $line);
}
return $output;
}
$input = array('Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6', 'Item 7');
$output = ReduceArray($input, 3);
print_r($output);
Output
Array
(
[0] => Item 1, Item 2, Item 3
[1] => Item 4, Item 5
[2] => Item 6, Item 7
)
Edit "fixed" the output as per the given output.
Edit See Comment for nine elements, tested for up to 12 elements. Thanks sectus
For each group, calculate to offset of the first element and the group length, copy that slice from the input array.
function array_group_elements($array, $groups) {
$result = array();
$count = count($array);
// minimum in each group
$limit = floor($count / $groups);
// balance, modulo
$overhead = $count % $groups;
// for each group
for ($i = 0; $i < $groups; ++$i) {
// group offset, add 1 for each group that got a balance element
$offset = ($i * $limit) + ($i < $overhead ? $i : $overhead);
// length, add 1 if it is a group with balance element
$length = $limit + ($i < $overhead ? 1 : 0);
// copy slice from original array
$result[] = array_slice($array, $offset, $length);
}
return $result;
}
$input = array('Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6', 'Item 7');
$grouped = array_group_elements($input, 3);
var_dump(
array_map(
function($group) {
return implode(', ', $group);
},
$grouped
)
);
Output:
array(3) {
[0]=>
string(22) "Item 1, Item 2, Item 3"
[1]=>
string(14) "Item 4, Item 5"
[2]=>
string(14) "Item 6, Item 7"
}
The function array_group_elements() loops over the $groups (3 times), not the $array (7 times).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With