英文:
Powershell split an array into 5 arrays with equal length
问题
抱歉,我只会翻译文本内容,不会回答要翻译的问题。以下是您提供的代码的翻译部分:
$MainArray = @(1,2,3,4,5,6,7,8,9,10,11)
结果:
> array1 = 1,2,3
>
> array2 = 4,5
>
> array3 = 6,7
>
> array4 = 8,9
>
> array5 = 10,11
这段代码中,将数组 $MainArray
分成了5个具有相等长度的数组。
英文:
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!
答案1
得分: 3
<!-- language-all: sh -->
要按要求执行元素分布,并将额外的元素添加到_初始_输出数组中,请使用以下方法。
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 }
}
}
注意:
* `[bool]`强制转换用作将_非零_值方便地映射为`1`,零映射为`0`的捷径,通过在_计算_上下文中使用生成的`[bool]`。
* `..` - [范围运算符](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Operators#range-operator-) - 用于从输入数组中提取数组片段,也是通过[`foreach`](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_Foreach)循环 `$parts` 次的简单方法。
* `,` - [数组构造运算符](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Operators#comma-operator-) - 以其一元形式用于将每个数组片段_作为整体_输出 - 请参阅[此答案](https://stackoverflow.com/a/56926132/45375)以获取解释。
示例调用,使用[`ConvertTo-Json`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/convertto-json)来可视化结果:
Split-array -inArray (1..11) -parts 5 |
ConvertTo-Json
输出(每个包含2-3个元素的5个数组):
[
[
1,
2,
3
],
[
4,
5
],
[
6,
7
],
[
8,
9
],
[
10,
11
]
]
英文:
<!-- language-all: sh -->
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 to1
and zero to0
, 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 aforeach
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
]
]
答案2
得分: 1
只返回翻译好的部分:
如果您跟踪创建的数组,您应该能够获得您想要的结果:
Function Split-Array {
Param(
[object]$InputObject,
[int]$Chunks
)
$track = 1
while ($InputObject.Count -gt 0 -and $track -le $Chunks) {
$chunk_size = [Math]::Min($InputObject.Count, [Math]::Ceiling($InputObject.Count / ($Chunks - $track + 1)))
$chunk = $InputObject[0..($chunk_size - 1)]
$InputObject = $InputObject[$chunk_size..($InputObject.Count - 1)]
,$chunk
$track++
}
}
while循环开始,只要满足以下任一条件,它将继续执行:
-
$array.Count -gt 0
:$array中的元素数量大于0。这意味着仍然有需要拆分为单独数组的元素。 -
$arrayIndex -le $arrayCount
:到目前为止创建的数组数量少于或等于$arrayCount
。这意味着您尚未创建所需数量的数组。
英文:
If you keep track of the arrays created, you should be able to get the results you're after:
Function Split-Array {
Param(
[object]$InputObject,
[int]$Chunks
)
$track = 1
while ($InputObject.Count -gt 0 -and $track -le $Chunks) {
$chunk_size = [Math]::Min($InputObject.Count, [Math]::Ceiling($InputObject.Count / ($Chunks - $track + 1)))
$chunk = $InputObject[0..($chunk_size - 1)]
$InputObject = $InputObject[$chunk_size..($InputObject.Count - 1)]
,$chunk
$track++
}
}
The while loop starts, and it will keep executing as long as either of these conditions are met:
-
$array.Count -gt 0
: The count of elements in $array is greater than
0. This means that there are still elements in $array that need to be split into separate arrays. -
$arrayIndex -le $arrayCount
: The number of arrays created so far is
less than or equal to$arrayCount
. This means that you haven't
created the desired number of arrays yet.
答案3
得分: 0
我的用例是从一个数组中填充哈希表,其中数组的元素数量未知,而我需要根据哈希表值中的其他条件来确定固定大小的数组值。
假设我的数组有3422个元素,我需要每个哈希值包含100个元素,以及最后一个添加到哈希表中的元素中的剩余部分。
然后:
[Math]::Floor(3422/100) 将给出所需的哈希元素数量。
我使用三个计数器:$i、$j 和 $k
例如:
$myArray = (get-<whatever> |select -exp Name)
$mySizeLimit = 100
$total = $myArray.count
$buckets = [math]::Floor($total/$mySizeLimit)
$myWrkHash = @{}
$j = 0; $k = 0;
for ($i = 0; $i -LE $buckets; $i++) {
if($i -LT $buckets) {
$k = $j + ($mySizeLimit - 1)
$myWrkHash.Add($i, $myArray[$j..$k])
$j+=$mySizeLimit
} elseif($i -EQ $buckets) {
$k = $total - 1
$myWrkHash.Add($i, $myArray[$j..$k])
}
}
英文:
My use-case for this is populating a hash with some unknown number of values from an array where I need a fixed size array value for the hash entries based on other criteria in my hash's values.
Lets say my array turns out to have 3422 elements and I need 100 per hash value plus whatever's left over for the last element added to the hash.
Then:
[Math]::Floor(3422/100) will give you the number of hash elements needed.
I use 3 counters: $i, $j and $k
For instance:
$myArray = (get-<whatever> |select -exp Name)
$mySizeLimit = 100
$total = $myArray.count
$buckets = [math]::Floor($total/$mySizeLimit)
$myWrkHash = @{}
$j = 0; $k = 0;
for ($i = 0; $i -LE $buckets; $i++) {
if($i -LT $buckets) {
$k = $j + ($mySizeLimit - 1)
$myWrkHash.Add($i, $myArray[$j..$k])
$j+=$mySizeLimit
} elseif($i -EQ $buckets) {
$k = $total - 1
$myWrkHash.Add($i, $myArray[$j..$k])
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论