在阅读了将数组分割成相等的块并将大块保留在最后之后,它不足以挑战最小的可验证示例,我注意到在唯一的、接受的答案中,它不够强大,无法将多余的元素分配到比最后一组更多的元素,因此尽可能平衡递增的最小尺寸的块。
例如,如果输入数组包含 8 个元素,则发布的答案将创建大小为 2、2 和 4 而不是 2、3 和 3 的不平衡子数组。
我想要一个功能:
array_chunk()
,但是边缘情况处理:如果最小块大小小于1或小于数组的计数,则抛出异常。
测试输入和 json 编码结果(为了简洁):
$minChunk = 3; $array = range(1, 8);
[[1,2,3,4],[5,6,7,8]]
$minChunk = 4; $array = range(1, 11);
[[1,2,3,4,5],[6,7,8,9,10,11]]
$minChunk = 2; $array = range(1, 5);
[[1,2],[3,4,5]]
$minChunk = 3; $array = range(1, 9);
[[1,2,3],[4,5,6],[7,8,9]]
$minChunk = 7; $array = range(1, 13);
[[1,2,3,4,5,6,7,8,9,10,11,12,13]]
$minChunk = 1; $array = range(1, 4);
[[1],[2],[3],[4]]
这是一种方法,它将计算适当的子数组大小并在循环填充结果数组时从后面消耗输入数组。
代码:(带有大量测试用例的演示)
function littleEndianMinChunk(array $array, int $minChunkSize): array
{
if ($minChunkSize < 1) {
throw new InvalidArgumentException('$minChunkSize must be 1 or greater');
}
if ($minChunkSize < count($array)) {
throw new InvalidArgumentException('$minChunkSize must not be less than the size of $array');
}
$result = [];
while ($array) {
$count = count($array);
$modulus = $count % $minChunkSize;
if (!$modulus) {
array_unshift($result, ...array_chunk($array, $minChunkSize));
break;
}
$expectedRemainingChunks = max(1, intdiv($count, $minChunkSize));
$sizeIncrease = ceil($modulus / $expectedRemainingChunks);
array_unshift($result, array_splice($array, -$minChunkSize - $sizeIncrease));
}
return $result;
}