I have the following variable defined
$A = New-Object -TypeName "System.Collections.ArrayList"
Now I add n
elements to it :
$A.Add(1..n)
Now I want to divide $A
into p
parts of k
elements each(The last one might have lesser elements if p*k>$A.count
).
How do I do that?
You can use a function to split an array into several smaller arrays. Below a slighty adapted version of that function found here:
function Split-Array {
[CmdletBinding(DefaultParametersetName = 'ByChunkSize')]
Param(
[Parameter(Mandatory = $true, Position = 0)]
$Array,
[Parameter(Mandatory = $true, Position = 1, ParameterSetName = 'ByChunkSize')]
[ValidateRange(1,[int]::MaxValue)]
[int]$ChunkSize,
[Parameter(Mandatory = $true, Position = 1, ParameterSetName = 'ByParts')]
[ValidateRange(1,[int]::MaxValue)]
[int]$Parts
)
$items = $Array.Count
switch ($PsCmdlet.ParameterSetName) {
'ByChunkSize' { $Parts = [Math]::Ceiling($items / $ChunkSize) }
'ByParts' { $ChunkSize = [Math]::Ceiling($items / $Parts) }
default { throw "Split-Array: You must use either the Parts or the ChunkSize parameter" }
}
# when the given ChunkSize is larger or equal to the number of items in the array
# use TWO unary commas to return the array as single sub array of the result.
if ($ChunkSize -ge $items) { return ,,$Array }
$result = for ($i = 1; $i -le $Parts; $i++) {
$first = (($i - 1) * $ChunkSize)
$last = [Math]::Min(($i * $ChunkSize) - 1, $items - 1)
,$Array[$first..$last]
}
return ,$result
}
In your case you could use it like:
$p = 4 # the number of parts you want
$subArrays = Split-Array $A.ToArray() -Parts $p
or
$k = 4 # the max number items in each part
$subArrays = Split-Array $A.ToArray() -ChunkSize $k