據我所知,PowerShell似乎沒有所謂的ternary operator的內置表達式。PowerShell中的三元運算符
例如,在C語言中,它支持三元運算符,我可以寫這樣的:
<condition> ? <condition-is-true> : <condition-is-false>;
如果實際上並不存在在PowerShell中,這將是最好的方式(即容易閱讀和維護)來完成相同的結果?
據我所知,PowerShell似乎沒有所謂的ternary operator的內置表達式。PowerShell中的三元運算符
例如,在C語言中,它支持三元運算符,我可以寫這樣的:
<condition> ? <condition-is-true> : <condition-is-false>;
如果實際上並不存在在PowerShell中,這將是最好的方式(即容易閱讀和維護)來完成相同的結果?
最近Powershell的結構,我已經能夠拿出來模擬那就是:
. ({'condition is false'},{'condition is true'})[$condition]
'({true},{false})[!$ condition]'稍微好一些(可能):a)傳統b)'$ condition'不一定是0或1或$ false,$ true。運算符'!'將它轉換爲需要的編輯。即'$ condition'可以是,比如42:!42〜$ false〜0〜第一個表達式。 –
不完全相同,@RomanKuzmin。 mjolinor的例子返回一個字符串。但是插入到表達式的示例中的相同字符串值將返回一個腳本塊。 :-( –
)通過'{true}'和'{false}'我的意思是'
由於指定值時,三元運營商通常使用,它應該返回一個值。這是可以工作的方式:
[email protected]("value if false","value if true")[[byte](condition)]
笨,但工作。也可以使用這種構造將int快速轉換爲另一個值,只需添加數組元素並指定一個返回基於0的非負值的表達式即可。
這將迫使對左右選項的急切評估:這與三元操作的適當性有很大不同 – user2864740
既然我已經使用過很多次,並沒有看到它列在這裏,我將添加我的作品:
$var = @{$true="this is true";$false="this is false"}[1 -eq 1]
最醜陋的所有!
這將迫使人們進行急切的評估左右選項:這與三元操作有很大不同 – user2864740
每本PowerShell blog post,您可以創建一個別名來定義?:
操作:
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})
這是一種比其他解決方案更可讀的方式! – Balmipour
似乎沒有理由'決定者'是一個腳本塊。如果'?:'被評估過,則需要評估參數。沒有腳本塊,它會有類似的用法,例如。 '(?:($ quantity -le 10){.9} {.75})' – user2864740
我也找了一個更好的回答,雖然愛德華的帖子中的解決方案是「好的」,但我想出了一個更加自然的方案solution in this blog post
簡短而親切:
# ---------------------------------------------------------------------------
# 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."
這使得它很容易做的東西一樣(在博客中更多的例子):
$message == ($age > 50) ? "Old Man" :"Young Dude"
這非常棒。我只是不喜歡使用'='作爲別名,因爲'=='在C#和許多其他語言中用於相等性檢查。在C#中有一些經驗在powershellers中很常見,並且使得產生的代碼有點混亂。 ':'可能是一個更好的別名。將它與變量賦值'=:'結合使用可能會提醒某人Pascal中使用的賦值,但在VB.NET和C#中沒有任何直接等價的(我知道的)。 – nohwnd
您可以將其設置爲任何你想要的別名。 ':'或'〜'或者其他什麼漂浮你的船。 :D 'set-alias:Invoke-Assignment -Option AllScope -Description「FearTheCowboy's Invoke-Assignment。」' #ternary '$ message =:($ age> 50)? 「老人」:「年輕人」 #null coalescing '$ message =:$ foo ?? 「foo是空的」' ' –
我知道,我做了,我只是在評論爲什麼我會使用別名。 – nohwnd
$result = If ($condition) {"true"} Else {"false"}
一切是偶然的複雜性,因此是避免。
對於或作爲表達,而不僅僅是分配的使用,包裝在$()
,從而:
write-host $(If ($condition) {"true"} Else {"false"})
在等號的右側工作,但不像您期望的三元運算符 - 這些失敗:*「a」+ If($ condition){「true」} Else {「false」} *和* 「a」+(If($ condition){「true」} Else {「false」})* 這有效(我還不確定爲什麼):*「a」+ $(If($ condition){ 「true」} else {「false」})* – Lamarth
@Lamarth - 這是因爲'$()'包裝器強制將語句評估爲表達式,因此返回false值的真實值,就像三元組運營商將被期望。這是您在PowerShell AFAIK中最接近的。 – KeithS
與其他「非函數」答案不同,這也會*確保只執行一個分支。 – user2864740
下面是一個替代的自定義功能的方法:
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'
差異說明
?
字符已經是Where-Object
的別名。??
在其他語言中用作空合併運算符,我想避免混淆。-2..2 |??? 'match' : 'nomatch'
給出:match, match, nomatch, match, match
(即,因爲任何非零int評估爲true
;而零評估爲false
)。([bool](-2..2)) |??? 'match' : 'nomatch'
(或簡稱:[bool](-2..2) |??? 'match' : 'nomatch'
)PowerShell中目前沒有一個本地Inline If(或ternary If),但你可以考慮使用自定義的cmdlet:
IIf <condition><condition-is-true><condition-is-false>
參見:
PowerShell Inline If (IIf)
鏈接的帖子顯示瞭如何創建一個'IIf'函數。但是,沒有標準的PowerShell'IIf'函數/ cmdlet。 – user2864740
@ user2864740,那又如何?這是否排除了答案作爲這個問題的可能答案:「*什麼是最好的方式(即易於閱讀和維護)來實現相同的結果?「*但是,除此之外,鏈接指的是IIf **問題**(發佈於2014年9月5日)與*非常相似(重複?)。鏈接問題中的其他答案也可以看出作爲附加價值(並且不這樣做,主要是因爲它們是重複的)。 – iRon
有一點解釋很長,這就是爲什麼*裸鏈接*不鼓勵,因爲如果存在重複則不會關閉沒有額外的附加信息,考慮一個非常小的解釋會顯着提高這種「裸鏈接」答案的質量:「Powershell不支持直接的'三元'(^但看其他答案)。但是,可以編寫一個函數,例如(^使用這種方法,或者查看其他答案)..「,但這不是我的*作業要添加。可以修改/更新/等等 – user2864740
嘗試powershell的開關聲明作爲替代,特別是對於變量賦值 - 多行,但可讀。
例,
$WinVer = switch (Test-Path $Env:windir\SysWOW64) {
$true { "64-bit" }
$false { "32-bit" }
}
"This version of Windows is $WinVer"
您可以使用:
$var = q(condition) ? condtion_is_true : condition_is_false
在https://github.com/nightroman/PowerShellTraps/tree/master/Basic/Missing-ternary-operator看看。如果這是你正在尋找的東西,我可以讓它成爲一個答案。 –
這是*條件*運算符或三元* if *。它不是「三元運算符」,因爲它意味着一個運算符(* any *運算符),它有三個參數。 –
@Damien_The_Unbeliever這在技術上是真實的,但它通常被稱爲三元運算符。_「由於該運算符通常是該語言中唯一存在的三元運算符,因此有時簡稱爲」三元運算符「。在某些語言中,該運算符被稱爲」條件運算符「。 (https://en.wikipedia.org/wiki/Ternary_operation) – mguassa