簡體   English   中英

如何在將PowerShell數組傳遞給函數時展開它

[英]How to expand a PowerShell array when passing it to a function

我有兩個PowerShell函數,第一個調用第二個函數。 它們都帶有N個參數,其中一個被定義為簡單地添加一個標志並調用另一個。 以下是示例定義:

function inner
{
  foreach( $arg in $args )
    {
      # do some stuff
    }
}

function outer
{
  inner --flag $args
}

用法看起來像這樣:

inner foo bar baz

或這個

outer wibble wobble wubble

目標是后一個例子等同於

inner --flag wibble wobble wubble

問題:如此處所定義,后者實際上導致兩個參數傳遞給inner :第一個是“--flag”,第二個是包含“wibble”,“wobble”和“wubble”的數組。 我想要的是inner接收四個參數:標志和三個原始參數。

所以我想知道如何說服powershell擴展$ args數組,然后將其傳遞給inner ,將其作為N個元素而不是單個數組傳遞。 我相信你可以使用splatting運算符(*字符)在Ruby中執行此操作,我很確定PowerShell可以做到這一點,但我不記得如何。

PowerSHell V1中沒有很好的解決方案。 在V2中我們添加了splatting(雖然出於各種原因,我們使用@而不是*來實現此目的)。 這是它的樣子:

PS(STA-ISS)(2)> function foo($ x,$ y,$ z){“x:$ xy:$ yz:$ z”}

PS(STA-ISS)(3)> $ a = 1,2,3

PS(STA-ISS)(4)> foo $ a#作為單個arg傳遞

x:1 2 3 y:z:

PS(STA-ISS)(5)> foo @a #splatted

x:1 y:2 z:3

好吧,可能有更好的方法,但看看這是否有效:

inner --flag [string]::Join(" ", $args)

基於@ EBGreen的想法以及我在側邊欄中注意到的相關問題,可能的解決方案是:

function outer
{
    invoke-expression "inner --flag $($args -join ' ')"
}

注意:此示例使用Powershell 2.0 CTP的新-join運算符。

但是,我仍然想找到一個更好的方法,因為這感覺就像一個黑客,而且安全性很差。

如果您想要一個快速的現成解決方案,您可以復制粘貼我的:

<#
    .SYNOPSIS
    Asks a question and waits for user's answer

    .EXAMPLE
    Usage with shortcuts and without ReturnValue
    Invoke-Question -Question "What would you like" -Answers "&Eggs", "&Toasts", "&Steak"

    Shows the quesiton and waits for input. Let's assume user input is 'S', the return value would be 2 (index of "&Steak")

    .EXAMPLE
    Usage without shortcuts and with ReturnValue
    Invoke-Question -Question "What would you like" -Answers "Eggs", "Toasts", "Steak" -ReturnValue

    Shows the quesiton and waits for input. The answers are prefixed with numbers 1, 2 and 3 as shortcuts.
    Let's assume user input is 2, the return value would be "Toasts" (prefixed numbers are "index + 1")

    .EXAMPLE
    Usage from pipeline with default value
    @("Eggs", "Toasts", "Steak") | Invoke-Question -Question "What would you like" -ReturnValue -Default 2

    Shows the quesiton and waits for input. The answers are taken from pipeline and prefixed with numbers 1, 2 and 3 as shortcuts.
    Steak is marked as default. If user simply continues without a choice, Steak is chosen for her.
    However, let's assume user input is 1, the return value would be "Eggs" (prefixed numbers are "index + 1")
#>
function Invoke-Question {
    [CmdletBinding()]
    param(
        # Main question text
        [Parameter(Mandatory = $true)]
        [string] $Question,

        # Question description, e.g. explanation or more information
        [Parameter(Mandatory = $false)]
        [string] $Description = "",

        # Default answer as index in the array, no answer is selected by default (value -1)
        [Parameter(Mandatory = $false)]
        [int] $Default = -1,

        # Set of answers, if the label is given with & sign, the prefixed letter is used as shortcut, e.g. "&Yes" -> Y,
        # otherwise the answer is prefixed with "index + 1" number as a shortcut
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string[]] $Answers,

        # If set, returns a value of selected answer, otherwise returns its index in the Answer array
        [switch] $ReturnValue
    )

    begin {
        # init choices
        $choices = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription]
        $answerNumber = 1
        $rememberAnswers = @()
    }

    process {
        #init answers
        foreach ($answer in $answers) {
            $rememberAnswers += $answer
            if ($answer -notmatch "&") {
                # add number if shortcut not specified
                $answer = "&$answerNumber $answer"
            }

            $choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList $answer))
            $answerNumber++
        }
    }

    end {
        # ask question and return either value or index
        $index = $Host.UI.PromptForChoice($Question, $Description, $choices, $Default)
        if ($ReturnValue) {
            $rememberAnswers[$index]
        } else {
            $index
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM