Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PowerShell中的三元算子_Powershell_Ternary Operator_Conditional Operator - Fatal编程技术网

PowerShell中的三元算子

PowerShell中的三元算子,powershell,ternary-operator,conditional-operator,Powershell,Ternary Operator,Conditional Operator,据我所知,PowerShell似乎没有所谓的 例如,在支持三元运算符的C语言中,我可以编写如下内容: <condition> ? <condition-is-true> : <condition-is-false>; ?:; 如果PowerShell中确实不存在这种情况,那么实现相同结果的最佳方法(即易于阅读和维护)是什么?我能想到的最接近的PowerShell结构是: @({'condition is false'},{'condition is tru

据我所知,PowerShell似乎没有所谓的

例如,在支持三元运算符的C语言中,我可以编写如下内容:

<condition> ? <condition-is-true> : <condition-is-false>;
?:;

如果PowerShell中确实不存在这种情况,那么实现相同结果的最佳方法(即易于阅读和维护)是什么?

我能想到的最接近的PowerShell结构是:

@({'condition is false'},{'condition is true'})[$condition]

由于赋值时通常使用三元运算符,因此它应该返回一个值。这是可行的方法:

$var=@("value if false","value if true")[[byte](condition)]

愚蠢,但工作。此外,此结构还可用于快速将int转换为另一个值,只需添加数组元素并指定一个返回基于0的非负值的表达式。

由于我已经多次使用此结构,但未在此处列出,因此我将添加我的内容:

$var=@{$true=“这是真的”;$false=“这是假的”}[1-等式1]

最丑的

根据此,您可以创建一个别名来定义
?:
运算符:

set-alias ?: Invoke-Ternary -Option AllScope -Description "PSCX filter alias"
filter Invoke-Ternary ([scriptblock]$decider, [scriptblock]$ifTrue, [scriptblock]$ifFalse) 
{
   if (&$decider) { 
      &$ifTrue
   } else { 
      &$ifFalse 
   }
}
像这样使用它:

$total = ($quantity * $price ) * (?:  {$quantity -le 10} {.9} {.75})
PS C:\Users\js> 0 ? 'yes' : 'no'
no
PS C:\Users\js> 1 ? 'yes' : 'no'
yes

我也在寻找一个更好的答案,虽然爱德华的帖子中的答案是“ok”,但我想出了一个更自然的答案

又短又甜:

# ---------------------------------------------------------------------------
# Name:   Invoke-Assignment
# Alias:  =
# Author: Garrett Serack (@FearTheCowboy)
# Desc:   Enables expressions like the C# operators: 
#         Ternary: 
#             <condition> ? <trueresult> : <falseresult> 
#             e.g. 
#                status = (age > 50) ? "old" : "young";
#         Null-Coalescing 
#             <value> ?? <value-if-value-is-null>
#             e.g.
#                name = GetName() ?? "No Name";
#             
# Ternary Usage:  
#         $status == ($age > 50) ? "old" : "young"
#
# Null Coalescing Usage:
#         $name = (get-name) ? "No Name" 
# ---------------------------------------------------------------------------

# returns the evaluated value of the parameter passed in, 
# executing it, if it is a scriptblock   
function eval($item) {
    if( $item -ne $null ) {
        if( $item -is "ScriptBlock" ) {
            return & $item
        }
        return $item
    }
    return $null
}

# an extended assignment function; implements logic for Ternarys and Null-Coalescing expressions
function Invoke-Assignment {
    if( $args ) {
        # ternary
        if ($p = [array]::IndexOf($args,'?' )+1) {
            if (eval($args[0])) {
                return eval($args[$p])
            } 
            return eval($args[([array]::IndexOf($args,':',$p))+1]) 
        }

        # null-coalescing
        if ($p = ([array]::IndexOf($args,'??',$p)+1)) {
            if ($result = eval($args[0])) {
                return $result
            } 
            return eval($args[$p])
        } 

        # neither ternary or null-coalescing, just a value  
        return eval($args[0])
    }
    return $null
}

# alias the function to the equals sign (which doesn't impede the normal use of = )
set-alias = Invoke-Assignment -Option AllScope -Description "FearTheCowboy's Invoke-Assignment."

其他一切都是偶然的复杂性,因此必须避免

要在表达式中使用或用作表达式,而不仅仅是赋值,请将其包装在
$()
中,从而:

write-host  $(If ($condition) {"true"} Else {"false"}) 

以下是另一种自定义函数方法:

function Test-TernaryOperatorCondition {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline = $true, Mandatory = $true)]
        [bool]$ConditionResult
        ,
        [Parameter(Mandatory = $true, Position = 0)]
        [PSObject]$ValueIfTrue
        ,
        [Parameter(Mandatory = $true, Position = 1)]
        [ValidateSet(':')]
        [char]$Colon
        ,
        [Parameter(Mandatory = $true, Position = 2)]
        [PSObject]$ValueIfFalse
    )
    process {
        if ($ConditionResult) {
            $ValueIfTrue
        }
        else {
            $ValueIfFalse
        }
    }
}
set-alias -Name '???' -Value 'Test-TernaryOperatorCondition'
示例

1 -eq 1 |??? 'match' : 'nomatch'
1 -eq 2 |??? 'match' : 'nomatch'
差异解释

  • 为什么是3个问号而不是1个?
    • 字符已经是
      Where Object
      的别名
    • ??
      在其他语言中用作空合并运算符,我希望避免混淆
  • 为什么我们在命令之前需要管道?
    • 因为我正在使用管道来评估这一点,所以我们仍然需要这个字符来将条件传递到我们的函数中
  • 如果我传入一个数组,会发生什么?
    • 我们得到每个值的结果;i、 e.
      -2..2| | | | | | | | | | | | | | 124match':'nomatch'
      给出:
      match,match,nomatch,match,match
      (即,由于任何非零int的计算结果为
      true
      ;而零的计算结果为
      false
    • 如果您不希望这样,请将数组转换为布尔值<代码>([bool](-2..2))|?'match':'nomatch'(或者简单地说:
      [bool](-2..2)|?'match':'nomatch'

PosikSeple目前没有<强>没有< /强>有一个本机(或),但您可以考虑使用自定义CMDLe:

IIf

请参阅:

尝试powershell的switch语句作为替代,特别是对于变量赋值-多行,但可读

例如

IIf <condition> <condition-is-true> <condition-is-false>
我最近改进了(open PullRequest)PoweShell库'Pscx'中的三元条件合并运算符和空合并运算符
请看看我的解决方案


我的github主题分支:

功能: 别名 用法
|?:
|?? 
作为您可以传递的表达式:
$null、文本、变量、外部表达式($b-eq 4)或脚本块{$b-eq 4}

如果变量表达式中的变量为$null或不存在,则替代表达式将作为输出进行计算。

Powershell 7拥有它


如果您只是在寻找一种语法上简单的方法来根据布尔条件分配/返回字符串或数字,则可以使用如下乘法运算符:

$total = ($quantity * $price ) * (?:  {$quantity -le 10} {.9} {.75})
PS C:\Users\js> 0 ? 'yes' : 'no'
no
PS C:\Users\js> 1 ? 'yes' : 'no'
yes
如果你只对真实的结果感兴趣,你可以完全忽略错误的部分(反之亦然),例如一个简单的评分系统:

"Condition is "+("true"*$condition)+("false"*!$condition)
(12.34*$condition)+(56.78*!$condition)

请注意,布尔值不应是乘法中的前导项,即$condition*“true”等将不起作用。

自PowerShell版本7起,三元运算符内置于PowerShell中

$isTall = $true
$isDark = $false
$isHandsome = $true

$score = (2*$isTall)+(4*$isDark)+(10*$isHandsome)
"Score = $score"
# or
# "Score = $((2*$isTall)+(4*$isDark)+(10*$isHandsome))"

PowerShell 7.0版引入了PowerShell中的三元运算符

1 -gt 2 ? "Yes" : "No"
# Returns "No"

1 -gt 2 ? 'Yes' : $null
# Get a $null response for false-y return value
例01

[Condition] ? (output if True) : (output if False)
输出

$a = 5; $b = 6
($a -gt $b) ? "True" : "False"
($a -gt $b) ? ("$a is greater than $b") : ("$a is less than $b")
例02

False
输出

$a = 5; $b = 6
($a -gt $b) ? "True" : "False"
($a -gt $b) ? ("$a is greater than $b") : ("$a is less than $b")
更多信息

看一看。如果这就是你要找的,我可以给你一个答案。它是一个条件运算符或三元If。这不是“三元运算符”,因为这意味着一个运算符(任何运算符)接受三个参数。@Damien_不相信这在技术上是正确的,但它通常被称为三元运算符。由于此运算符通常是语言中唯一存在的三元运算符,因此有时被简单地称为“三元运算符”。在某些语言中,此运算符被称为“条件运算符”。“Visual basic没有真正的三元运算符,但认为IF和IFF在功能上是等效的。三元运算符在版本7中添加到本机PowerShell中。相应地添加了一个答案。
({true},{false})[!$condition]
稍微好一点(也许):a)正确和错误部分的传统顺序;b)
$condition
不必仅为0或1或$false、$true。操作员
根据需要对其进行转换。例如,
$condition
可以是42:!42~$false~0~第一个表达式。不完全相同,@RomanKuzmin。mjolinor的示例返回一个字符串。但将其示例中的相同字符串值插入到表达式中会返回一个脚本块:-(通过
{true}
{false}
我的意思是
,而不是脚本块。很抱歉不准确。感谢您的澄清,@RomanKuzmin--现在我看到了您建议中的价值。这将强制对左选项和右选项进行急切的评估:这与正确的三元运算大不相同。它在equals的右侧工作,但不会退出正如您所期望的三元运算符一样,这些运算符失败:“a”+If($condition){“true”}Else{“false”}和“a”+(If($condition){“true”}Else{“false”})这是有效的(我还不确定)
False
($a -gt $b) ? ("$a is greater than $b") : ("$a is less than $b")
5 is less than 6