Powershell将一个数组分成5个等长度的数组

huangapple go评论62阅读模式
英文:

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 Powershell将一个数组分成5个等长度的数组 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 &quot;$parts sub-arrays requested, but the input array has only $($inArray.Count) elements.&quot; }
  $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
  ]
]

答案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-&lt;whatever&gt; |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])
    }
}

huangapple
  • 本文由 发表于 2023年2月6日 10:27:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75356847.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定