Toán tử bậc ba trong PowerShell

240
mguassa 2015-07-11 03:26.

Theo những gì tôi biết, PowerShell dường như không có một biểu thức tích hợp cho cái gọi là toán tử bậc ba .

Ví dụ, trong ngôn ngữ C, hỗ trợ toán tử bậc ba, tôi có thể viết một cái gì đó như:

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

Nếu điều đó không thực sự tồn tại trong PowerShell, thì đâu sẽ là cách tốt nhất (tức là dễ đọc và dễ bảo trì) để đạt được kết quả tương tự?

13 answers

352
fbehrens 2015-12-17 01:44.
$result = If ($condition) {"true"} Else {"false"}

Mọi thứ khác là sự phức tạp ngẫu nhiên và do đó cần tránh.

Để sử dụng trong hoặc dưới dạng một biểu thức, không chỉ là một phép gán, hãy gói nó vào $(), do đó:

write-host  $(If ($condition) {"true"} Else {"false"}) 
67
mjolinor 2015-07-11 03:52.

Cấu trúc PowerShell gần nhất mà tôi có thể nghĩ ra để mô phỏng đó là:

@({'condition is false'},{'condition is true'})[$condition]
38
js2010 2019-10-08 04:19.

Powershell 7 có nó. https://toastit.dev/2019/09/25/ternary-operator-powershell-7/

PS C:\Users\js> 0 ? 'yes' : 'no'
no
PS C:\Users\js> 1 ? 'yes' : 'no'
yes
24
Edward Brey 2015-11-13 03:01.

Theo bài đăng trên blog PowerShell này , bạn có thể tạo một bí danh để xác định một ?:toán tử:

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

Sử dụng nó như thế này:

$total = ($quantity * $price ) * (?:  {$quantity -le 10} {.9} {.75})
22
Garrett Serack 2015-12-12 09:21.

Tôi cũng vậy, đã tìm kiếm một câu trả lời tốt hơn và trong khi giải pháp trong bài đăng của Edward là "ok", tôi đã đưa ra một giải pháp tự nhiên hơn nhiều trong bài đăng trên blog này

Ngắn và ngọt:

# ---------------------------------------------------------------------------
# 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."

Điều này giúp bạn dễ dàng thực hiện những thứ như (thêm ví dụ trong bài đăng trên blog):

$message == ($age > 50) ? "Old Man" :"Young Dude" 
18
nudl 2018-01-18 01:42.

Hãy thử câu lệnh switch của powershell như một giải pháp thay thế, đặc biệt đối với gán biến - nhiều dòng, nhưng có thể đọc được.

Thí dụ,

$WinVer = switch ( Test-Path $Env:windir\SysWOW64 ) {
  $true    { "64-bit" }
  $false   { "32-bit" }
}
"This version of Windows is $WinVer"
13
Trevor Sullivan 2020-06-20 05:38.

Kể từ phiên bản PowerShell 7, toán tử bậc ba được tích hợp vào PowerShell.

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

1 -gt 2 ? 'Yes' : $null
# Get a $null response for false-y return value
10
Vesper 2015-07-11 04:16.

Vì toán tử bậc ba thường được sử dụng khi gán giá trị, nên nó sẽ trả về một giá trị. Đây là cách có thể hoạt động:

[email protected]("value if false","value if true")[[byte](condition)]

Ngu ngốc, nhưng làm việc. Ngoài ra, cấu trúc này có thể được sử dụng để nhanh chóng chuyển một int thành một giá trị khác, chỉ cần thêm các phần tử mảng và chỉ định một biểu thức trả về các giá trị không âm dựa trên 0.

6
sodawillow 2015-09-17 08:44.

Vì tôi đã sử dụng cái này nhiều lần rồi và không thấy nó được liệt kê ở đây, tôi sẽ thêm phần của mình:

$var = @{$true="this is true";$false="this is false"}[1 -eq 1]

xấu xí nhất trong tất cả!

nguồn kinda

5
andiDo 2018-06-12 05:37.

Gần đây tôi đã cải thiện (mở PullRequest) các toán tử có điều kiện bậc ba và liên kết rỗng trong PoweShell lib 'Pscx'.
Xin hãy xem giải pháp của tôi.


Nhánh chủ đề github của tôi: UtilityModule_Invoke-Operators

Chức năng:

Invoke-Ternary
Invoke-TernaryAsPipe
Invoke-NullCoalescing
NullCoalescingAsPipe

Bí danh

Set-Alias :?:   Pscx\Invoke-Ternary                     -Description "PSCX alias"
Set-Alias ?:    Pscx\Invoke-TernaryAsPipe               -Description "PSCX alias"
Set-Alias :??   Pscx\Invoke-NullCoalescing              -Description "PSCX alias"
Set-Alias ??    Pscx\Invoke-NullCoalescingAsPipe        -Description "PSCX alias"

Sử dụng

<condition_expression> |?: <true_expression> <false_expression>

<variable_expression> |?? <alternate_expression>

Là biểu thức, bạn có thể truyền:
$ null, một ký tự, một biến, một biểu thức 'bên ngoài' ($ b -eq 4) hoặc một scriptblock {$ b -eq 4}

Nếu một biến trong biểu thức biến là $ null hoặc không tồn tại , biểu thức thay thế được đánh giá là đầu ra.

4
iRon 2017-07-23 00:52.

PowerShell hiện không có If nội tuyến gốc (hoặc If thứ ba ) nhưng bạn có thể cân nhắc sử dụng lệnh ghép ngắn tùy chỉnh:

IIf <condition> <condition-is-true> <condition-is-false>
Xem: PowerShell Inline If (IIf)

1
JohnLBevan 2017-06-14 06:38.

Đây là một cách tiếp cận chức năng tùy chỉnh thay thế:

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'

Thí dụ

1 -eq 1 |??? 'match' : 'nomatch'
1 -eq 2 |??? 'match' : 'nomatch'

Sự khác biệt được giải thích

  • Tại sao lại là 3 dấu hỏi thay vì 1?
    • Nhân ?vật đã là một bí danh cho Where-Object.
    • ?? được sử dụng trong các ngôn ngữ khác như một toán tử liên kết rỗng và tôi muốn tránh nhầm lẫn.
  • Tại sao chúng ta cần đường dẫn trước lệnh?
    • Vì tôi đang sử dụng đường dẫn để đánh giá điều này, chúng tôi vẫn cần ký tự này để chuyển điều kiện vào chức năng của chúng tôi
  • Điều gì xảy ra nếu tôi chuyển vào một mảng?
    • Chúng tôi nhận được một kết quả cho mỗi giá trị; tức là -2..2 |??? 'match' : 'nomatch'cho: match, match, nomatch, match, match(nghĩa là vì bất kỳ int nào khác 0 đều đánh giá là true; trong khi 0 đánh giá là false).
    • Nếu bạn không muốn điều đó, hãy chuyển đổi mảng thành bool; ([bool](-2..2)) |??? 'match' : 'nomatch'(hoặc đơn giản [bool](-2..2) |??? 'match' : 'nomatch':)
1
nmbell 2020-03-01 17:52.

Nếu bạn chỉ đang tìm kiếm một cách đơn giản về mặt cú pháp để gán / trả về một chuỗi hoặc số dựa trên điều kiện boolean, bạn có thể sử dụng toán tử nhân như sau:

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

Nếu bạn chỉ quan tâm đến kết quả khi điều gì đó là đúng, bạn chỉ có thể bỏ qua hoàn toàn phần sai (hoặc ngược lại), ví dụ: một hệ thống tính điểm đơn giản:

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

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

Lưu ý rằng giá trị boolean không được là số hạng đứng đầu trong phép nhân, tức là $ condition * "true", v.v. sẽ không hoạt động.

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Một thương hiệu kế thừa khác có được cuộc sống mới khi những người chủ mới của Black Opal có được Hội chợ thời trang

Một thương hiệu kế thừa khác có được cuộc sống mới khi những người chủ mới của Black Opal có được Hội chợ thời trang

Desiree Rogers, trái, và Cheryl Mayberry McKissack Chuyển sang, Fenty Beauty và Pat McGrath, có một đế chế làm đẹp mới do phụ nữ làm chủ đang trỗi dậy. Sau thương vụ mua lại mỹ phẩm Black Opal vào tháng 9, đội ngũ quyền lực của Giám đốc điều hành công ty Desiree Rogers và Chủ tịch Cheryl Mayberry McKissack đã thông báo mua lại thương hiệu làm đẹp tiên phong Fashion Fair từ người sáng lập Johnson Publishing Company (JPC).

Ngoài việc trở nên vô nghĩa, các bên bộc lộ giới tính giờ đây đã trở nên chết người

Ngoài việc trở nên vô nghĩa, các bên bộc lộ giới tính giờ đây đã trở nên chết người

Đối với những người có quá nhiều thời gian, tiệc tiết lộ giới tính là một cách thú vị để không cần áp đặt những định kiến ​​hạn chế lên thai nhi trước một đối tượng bạn bè giả vờ quan tâm một cách lịch sự. Tuy nhiên, việc chỉ dựa vào những chiếc bánh nướng có màu nhân tạo để biểu thị một tiếng hoo-ha hoặc một đứa trẻ đi tè đã trở nên xa xỉ trong các bậc cha mẹ trên Instagram.

Kirstjen Nielsen đang cố gắng đổi mới bản thân với tư cách là một người phụ nữ 'nói ra sự thật cho sức mạnh'

Kirstjen Nielsen đang cố gắng đổi mới bản thân với tư cách là một người phụ nữ 'nói ra sự thật cho sức mạnh'

Hôm thứ Tư, cựu Bộ trưởng An ninh Nội địa Kirstjen Nielsen vì một lý do nào đó đã được đưa ra một diễn đàn để phát biểu tại Hội nghị thượng đỉnh Những người phụ nữ quyền lực nhất của Fortune. Và có thể đoán trước được, người phụ nữ giám sát các nỗ lực (đang diễn ra) của chính quyền Trump nhằm chia cắt các gia đình ở biên giới đã sử dụng thời gian của mình như một cơ hội để tự bảo vệ mình và tự nhận mình là người — và hãy hít thở sâu ở đây — “đã nói sự thật với quyền lực.

Toyota Racing Development sẽ cho ra mắt Supra 3000GT Concept, Massive Wing vào tháng tới

Toyota Racing Development sẽ cho ra mắt Supra 3000GT Concept, Massive Wing vào tháng tới

Vì thế hệ mới nhất của chiếc xe điều chỉnh được yêu thích trên thế giới hiện đã có mặt tại đây, nên chỉ có điều kiện là Toyota Racing Development sẽ đưa phiên bản Supra thế hệ thứ năm sửa đổi của riêng mình đến SEMA vào tháng tới. Toyota đã cho chúng tôi một gợi ý về những gì sẽ xảy ra trong tuần này: một chiếc Concept GR Supra 3000GT hiện đại.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language