细分值列表

时间:2011-03-28 02:44:58

标签: powershell

我正在编写一些代码来弄清楚如何将值列表分成更易于管理的块。我想这样做的原因是因为我将拥有大约100,000个实时值,并且我希望最大限度地降低失败风险。


$wholeList = 1..100

$nextStartingPoint

$workingList

function Get-NextTenItems()
{
    $workingList = (1+$nextStartingPoint)..(10+$nextStartingPoint)

    $nextStartingPoint += 10

    Write-Host "inside Get-NextTenItems"
    write-host "Next StartingPoint: $nextStartingPoint"
    $workingList
    Write-Host "exiting Get-NextTenItems"
}

function Write-ListItems()
{
    foreach ($li in $workingList)
    {
        Write-Host $li
    }
}
Get-NextTenItems
Write-ListItems
Get-NextTenItems
Write-ListItems

我在PowerGUI调试器中运行了代码,当我退出Get-NextTenItems函数时,我注意到我的$ nextStartingPoint重置为0。

为什么会发生这种情况,我该如何预防呢?

我是否还应该假设$ workingList发生了同样的事情?

3 个答案:

答案 0 :(得分:3)

我的建议是使用管道。一个函数产生块,另一个函数消耗它们。

使用这种方法,您不需要污染全局/脚本范围,这不是一个好主意。所需的一切都保存在需要它的功能中。

function Get-Chunk
{
    param(
        [Parameter(Mandatory=$true)]$collection, 
        [Parameter(Mandatory=$false)]$count=10
    )
    #temporary array
    $tmp = @()
    $i = 0
    foreach($c in $collection) {
        $tmp += $c                  # add item $c to array
        $i++                        # increase counter; indicates that we reached chunk size
        if ($i -eq $count) {
            ,$tmp                   # send the temporary array to the pipeline
            $i = 0                  # reset variables
            $tmp = @()         
        }
    }
    if ($tmp)  {                    # if there is something remaining, send it to the pipeline
        ,$tmp
    }
}

function Write-ListItems
{
    param(
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]$chunk
    )
    process {
        write-host Chunk: "$chunk"
    }
}

测试功能:

$wholeList = 1..100
Get-Chunk $wholeList | Write-ListItems
Chunk: 1 2 3 4 5 6 7 8 9 10
Chunk: 11 12 13 14 15 16 17 18 19 20
Chunk: 21 22 23 24 25 26 27 28 29 30
Chunk: 31 32 33 34 35 36 37 38 39 40
Chunk: 41 42 43 44 45 46 47 48 49 50
Chunk: 51 52 53 54 55 56 57 58 59 60
Chunk: 61 62 63 64 65 66 67 68 69 70
Chunk: 71 72 73 74 75 76 77 78 79 80
Chunk: 81 82 83 84 85 86 87 88 89 90
Chunk: 91 92 93 94 95 96 97 98 99 100

Get-Chunk $wholeList 32 | Write-ListItems
Chunk: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
Chunk: 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
Chunk: 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
Chunk: 97 98 99 100

<强>更新

我添加了一些评论以澄清事情。注意,当向管道发送内容时(a)我不使用return,因为我会从函数中跳出来。 (b)开头的逗号将$tmp的内容包装到数组中,因此它创建一个包含一个项目的新数组(这是N个项目的数组)。为什么?因为在PowerShell中有自动展开,这将从数组中解开项目并将所有项目展平 - &gt;结果将是一个大阵列。

示例:

function Get-Arrays {
  1,2,3
  "a", "b"
  ,(get-date)
  4,5,6
}
Get-Arrays | % { "$_" }

这可以按预期工作:

function Get-Arrays {
  ,(1,2,3)
  ,("a", "b")
  ,(get-date)
  ,(4,5,6)
}
Get-Arrays | % { "$_" }

答案 1 :(得分:2)

在您的示例Get-NextTenItems中更改其本地变量。有几种方法可以解决此问题,其中有两种方法:

1)明确指定变量范围(使用前缀scriptglobal)。也就是说,在函数内使用变量$script:nextStartingPoint$script:workingList

2)更改其通话中的功能范围。即,使用点运算符(“dot-source”函数)调用函数,即在当前作用域中执行它。此代码按预期工作(无需其他更改):

. Get-NextTenItems
Write-ListItems
. Get-NextTenItems
Write-ListItems 

另见

help about_scopes

答案 2 :(得分:1)

前面的答案还可以。但它不完整,它允许你以某种方式编码不可读。在纯粹的编程观点上,您还有另外两种方法可以将参数传递给过程(或函数),其中一种方法允许您修改参数。

<强> 1。按值的参数(常见方式)

使用这种方式记录函数使用的参数

Function addition ([int]$x, [int]$y) {
  $x + $y
}

<强> 2。参数参数(通过引用调用一种指针)

使用这种方式,最后一个参数可以修改为你的函数。

function addition ([int]$x, [int]$y, [ref]$R) {
 $Res = $x * $y
 $R.value = $Res
}

# usage
addition $A $B ([ref]$C)

在使用第二个解决方案的代码中:

  1. 允许您将变量修改为函数
  2. 让其他读者了解此功能可以修改其中一个参数
  3. 的功能

    我希望它有所帮助。