2012-12-15 84 views
2

例如,給定列表1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8和數字4,它返回長度爲4的列表的列表,即 (1, 2, 3, 4), (5, 6, 7, 8), (1, 2, 3, 4), (5, 6, 7, 8)Powershell將一個長陣列分成長度爲N的數組在一行中?

基本上我想在Powershell中實現下面的Python代碼。

s = 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8 
z = zip(*[iter(s)]*4) # Here N is 4 
# z is (1, 2, 3, 4), (5, 6, 7, 8), (1, 2, 3, 4), (5, 6, 7, 8) 

以下腳本返回的17代替5.

$a = 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,0 
$b = 0..($a.Length/4) | % { @($a[($_*4)..($_*4 + 4 - 1)]) } 
$b.Length 
+0

很好的解決方案。你將如何處理N個不能被N整除的元素?在這種情況下是4。 $ a = 1..18 –

+0

@DougFinke創建一個變量'$ n = 4',並用'$ n'替換所有的4s應該可以工作。 – ca9163d9

+0

同意。我想我問的是。當你有一組不可被N整除的數組時,你如何處理左邊的邊界? –

回答

5
PS> $a = 1..16 
PS> $z=for($i=0; $i -lt $a.length; $i+=4){ ,($a[$i]..$a[$i+3])} 
PS> $z.count 
4  

PS> $z[0] 
1 
2 
3 
4 

PS> $z[1] 
5 
6 
7 
8 

PS> $z[2] 
9 
10 
11 
12 

PS> $z[3] 
13 
14 
15 
16 
+1

接受的解決方案僅適用於連續整數。 例如,當$ i是0時,$ a [$ i]是1,$ a [$ i + 3]是4,因此1 .. 4將起作用。但正確的解決方案是 '$ z = for($ i = 0; $ i -lt $ a.length; $ i + = 4){,($ a [$ i ..($ i + 3)]) }' –

6

寫到這在2009年PowerShell Split-Every Function

大概可以得到改善。

Function Split-Every($list, $count=4) { 
    $aggregateList = @() 

    $blocks = [Math]::Floor($list.Count/$count) 
    $leftOver = $list.Count % $count 
    for($i=0; $i -lt $blocks; $i++) { 
     $end = $count * ($i + 1) - 1 

     $aggregateList += @(,$list[$start..$end]) 
     $start = $end + 1 
    }  
    if($leftOver -gt 0) { 
     $aggregateList += @(,$list[$start..($end+$leftOver)]) 
    } 

    $aggregateList  
} 

$s = 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8 

$r = Split-Every $s 4 

$r[0] 
"" 
$r[1] 
"" 
$r[2] 
"" 
$r[3] 
+0

如果列表的長度是<$ count,那麼$ startList和$ end將在未初始化的$ aggregateList代碼中使用(或設置爲未知值)。 修正是在for循環上面添加$ start = $ end = 0。 – lovedatsnow

1
$a = 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,0 
$b = 0..([Math]::ceiling($a.Length/4) - 1) | 
    % { @(, $a[($_*4)..($_*4 + 4 - 1)]) } 

不知道爲什麼,我不得不把一個逗號(後。

1

清除,主機

$ S = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 ,18

$計數= $ s.Length

$分裂= $計數/ 2

$分裂 -

$ b $ = S [0 .. $分裂]

$分裂++

$ a = $ S [$分裂.. $計數]

寫主機 「第一陣列」

$ B

寫主機「下一個陣」

$一個

清理

獲取變量 - 排除PWD,*偏好|刪除 - 變量-EA 0

+1

您能否在此答案中添加更多詳細信息?這只是代碼而已,所以有點解釋會很好 – KhorneHoly

11

這有點舊,但我想我會拋出我用於將數組拆分爲塊的方法。您可以使用組,對象與構造屬性:

$bigList = 1..1000 

$counter = [pscustomobject] @{ Value = 0 } 
$groupSize = 100 

$groups = $bigList | Group-Object -Property { [math]::Floor($counter.Value++/$groupSize) } 

$groups會的GroupInfo對象的集合;在這種情況下,每個組將具有100個元素(可通過$groups[0].Group$groups[1].Group等訪問)。我使用計數器的對象屬性來避免-Property腳本塊內的作用域問題,因爲簡單的$i++不會寫入回到原來的變量。或者,您可以使用$script:counter = 0$script:counter++,並獲得沒有自定義對象的相同效果。

+0

這是美的事情,謝謝! – Froosh

+0

我想使用這個,但我需要先由一個附加屬性進行分組。每當'baseomain'屬性更改時,我怎樣才能讓'$ counter'重置? –

+0

明白了:看我的答案http://serverfault.com/a/823936/190386 –

1

@Shay Levy答案:如果您將a的值更改爲1 ..15那麼你的解決方案不工作了(彼得Reavy評論)

所以這個工作對我來說:

$a = 1..15 
$z=for($i=0; $i -lt $a.length; $i+=4){if ($a.length -gt ($i+3)) { ,($a[$i]..$a[$i+3])} else { ,($a[$i]..$a[-1])}} 
$z.count