Hello everyone hope you are all doing great! been searching but cannot get it right :( could it be possible for you to help me, please? Need to split an array into 5 arrays with equal length, for example.
$MainArray = @(1,2,3,4,5,6,7,8,9,10,11)
Result:
array1 = 1,2,3
array2 = 4,5
array3 = 6,7
array4 = 8,9
array5 = 10,11
Each array as even as possible (order doesn't matters) has this and it splits but not as even as I would like to.
Currently, I have this (searched on the internet already)
function Split-Array {
[CmdletBinding()]
param(
[Object] $inArray,
[int]$parts
)
if ($inArray.Count -eq 1) { return $inArray }
$PartSize = [Math]::Ceiling($inArray.count / $parts)
$outArray = New-Object 'System.Collections.Generic.List[psobject]'
for ($i = 1; $i -le $parts; $i++) {
$start = (($i - 1) * $PartSize)
$end = (($i) * $PartSize) - 1
if ($end -ge $inArray.count) {$end = $inArray.count - 1}
$outArray.Add(@($inArray[$start..$end]))
}
return , $outArray
}
Split-array -inArray $MainArray -parts 5
This function splits the $MainArray
into 5 arrays but not as even, the result is:
array1 = 1,2,3
array2 = 4,56
array3 = 7,8,9
array4 = 10,11
array5 = 11
It even errors adding 11 into 2 arrays. My brain is burned at this moment, haha any help would be much appreciated. thanks!
To perform the element distribution as requested - with extra elements getting added to the initial output arrays - use the following.
function Split-Array {
[CmdletBinding()]
param(
[object[]] $inArray,
[int] $parts
)
[int] $partSize = [Math]::Floor($inArray.count / $parts)
if ($partSize -eq 0) { throw "$parts sub-arrays requested, but the input array has only $($inArray.Count) elements." }
$extraSize = $inArray.Count - $partSize * $parts
$offset = 0
foreach ($i in 1..$parts) {
, $inArray[$offset..($offset + $partSize + [bool] $extraSize - 1)]
$offset += $partSize + [bool] $extraSize
if ($extraSize) { --$extraSize }
}
}
Note:
[bool]
casts are used as a convenient shortcut to map nonzero values to 1
and zero to 0
, via using the resulting [bool]
in the context of calculations.
..
- the range operator - is used to extract array slices from the input array, and also as a simple way to loop $parts
times via a foreach
loop.
,
- the array constructor operator - is used in its unary form to output each array slice as a whole - see this answer for an explanation.
Sample call, which uses ConvertTo-Json
to visualize the results:
Split-array -inArray (1..11) -parts 5 |
ConvertTo-Json
Output (5 arrays with 2-3 elements each):
[
[
1,
2,
3
],
[
4,
5
],
[
6,
7
],
[
8,
9
],
[
10,
11
]
]