পাওয়ারশেলে টেরানারি অপারেটর


214

আমি যা জানি, পাওয়ারশেলের তথাকথিত টের্নারি অপারেটরের জন্য অন্তর্নির্মিত প্রকাশ নেই বলে মনে হয় ।

উদাহরণস্বরূপ, সি ভাষায়, যা টের্নারি অপারেটরকে সমর্থন করে আমি এই জাতীয় কিছু লিখতে পারি:

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

যদি পাওয়ারশেলের মধ্যে এটি সত্যিই বিদ্যমান না থাকে, তবে একই ফলাফলটি সম্পাদন করার সবচেয়ে ভাল উপায় (অর্থাত্ সহজভাবে পড়া এবং বজায় রাখা) কী হতে পারে?


5
গিথুব / নাইট্রোম্যান / পাওয়ারশেলট্র্যাপস / ট্র্রি / মাস্টার / বেসিক / atএ একবার দেখুন । আপনি যদি এটির সন্ধান করেন তবে আমি এটি একটি উত্তর দিতে পারি।
রোমান কুজমিন

2
এটি শর্তসাপেক্ষ অপারেটর বা টেরিনারি যদি হয় । এটি "টার্নারি অপারেটর" নয় কারণ এর অর্থ সমস্ত অপারেটর ( যে কোনও অপারেটর) যা তিনটি আর্গুমেন্ট নেয়।
দামিয়েন_তিনি_বিশ্বাসীরা

7
@ ড্যামিয়েন_সে_ অবিশ্বাসী এটি প্রযুক্তিগতভাবে সত্য, তবে এটি প্রায়শই টার্নারি অপারেটর নামে পরিচিত। "যেহেতু এই অপারেটরটি প্রায়শই ভাষায় একমাত্র বিদ্যমান টেরিনারি অপারেটর, তাই এটি কখনও কখনও" টার্নারি অপারেটর "হিসাবেও পরিচিত হয় some কিছু ভাষায় এই অপারেটরটিকে" শর্তসাপেক্ষ অপারেটর "হিসাবে অভিহিত করা হয়
T

ভিজ্যুয়াল বেসিকের সত্যিকারের টেরিনারি অপারেটর নেই তবে আইএফ এবং আইএফএফকে কার্যকরীভাবে ন্যায়সঙ্গত হিসাবে বিবেচনা করে।
ম্যাট

@ ম্যাট এটি ভুল। IIF ফাংশন সবসময় উভয় operands মূল্যায়ন করবো। Ifবিবৃতি করা হবে না - দেখুন stackoverflow.com/questions/1220411/... : (নতুন VB.NET সংস্করণ একটি তিন অভিব্যক্তি যোগ If (x, y, z))
user2864740

উত্তর:


319
$result = If ($condition) {"true"} Else {"false"}

সমস্ত কিছু ঘটনামূলক জটিলতা এবং তাই এড়ানো যায়।

কেবল কোনও অ্যাসাইনমেন্ট নয়, একটি অভিব্যক্তি বা হিসাবে প্রকাশের জন্য এটি এটিকে মোড়ানো রাখুন $():

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

3
এটি একটি সমান অংশের ডানদিকে কাজ করে, তবে আপনি যেমন কোনও টার্নারি অপারেটরের প্রত্যাশা করেননি ঠিক তেমন নয় - এগুলি ব্যর্থ হয়: "এ" + যদি ($ শর্ত) true "সত্য"} অন্যথায় false "মিথ্যা"} এবং "একটি" + (যদি ($ শর্ত) {"সত্য"} অন্যথায় false "মিথ্যা"}) এটি কাজ করে (কেন আমি এখনও তা নিশ্চিত নই): "ক" + $ (যদি ($ শর্ত) true "সত্য"} অন্যথায় {"মিথ্যা "})
ল্যামার্থ

12
@ ল্যামার্থ - এটি কাজ করে কারণ মোড়কগুলি $()বিবৃতিটিকে একটি অভিব্যক্তি হিসাবে মূল্যায়ন করতে বাধ্য করে, সুতরাং মিথ্যা মানটির সত্যিকারের মানটি প্রত্যাবর্তন করে, অনেকটা এক দশক অপারেটরের মতো প্রত্যাশিত। এটি পাওয়ারশেল এএফআইকে আপনি সবচেয়ে কাছের পাবেন।
কিথস

4
অন্যান্য কিছু "নন ফাংশন" উত্তরগুলির বিপরীতে, এটিও নিশ্চিত করে যে কেবলমাত্র একটি শাখা কার্যকর করা হয়েছে।
ব্যবহারকারী 2864740

63

নিকটতম পাওয়ারশেল নির্মাণটি আমি অনুকরণ করতে সক্ষম হয়েছি তা হ'ল:

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

15
({true}, {false})[!$condition]কিছুটা ভাল (সম্ভবত): ক) সত্য এবং মিথ্যা অংশের traditionalতিহ্যগত ক্রম; খ) $conditionকেবল 0 বা 1 বা $ মিথ্যা, $ সত্য হতে হবে না। অপারেটর !এটি প্রয়োজনীয় হিসাবে রূপান্তর করে। অর্থাৎ $condition, বলতে পারেন, 42 :! 42 ~ $ মিথ্যা ~ 0 ~ প্রথম অভিব্যক্তি।
রোমান কুজমিন

1
@ রমনকুজমিন, একদম অভিন্ন নয়। mjolinor এর উদাহরণটি একটি স্ট্রিং দেয়। তবে তার উদাহরণ থেকে একই স্ট্রিং মানগুলি আপনার এক্সপ্রেশনটিতে প্লাগ ইন করে একটি স্ক্রিপ্ট ব্লক দেয়। :-(
মাইকেল সোরেন্স

5
দ্বারা {true}এবং {false}আমি বলতে চাইছি <true expression>এবং <false expression>স্ক্রিপ্ট ব্লকগুলি নয়। সঠিক না হওয়ার জন্য দুঃখিত।
রোমান কুজমিন

1
স্পষ্টকরণের জন্য ধন্যবাদ, @ রোমানকুজমিন - এখন আমি আপনার পরামর্শে মানটি দেখতে পাচ্ছি।
মাইকেল সোরেন্স

12
এটি বাম এবং ডান বিকল্পগুলির উত্সাহ-মূল্যায়নের জন্য বাধ্য করবে: এটি একটি সঠিক টার্নারি অপারেশন থেকে অনেক আলাদা।
ব্যবহারকারী 2864740

24

এই পাওয়ারশেল ব্লগ পোস্টের জন্য , আপনি ?:অপারেটর সংজ্ঞায়িত করতে একটি নাম তৈরি করতে পারেন :

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})

'সিদ্ধান্তদাতা' স্ক্রিপ্টব্লক হওয়ার কোনও কারণ বলে মনে হয় না। যদি ?:কখনও মূল্যায়ন হয় তবে এটির জন্য আর্গুমেন্টগুলি মূল্যায়ন করা দরকার। স্ক্রিপ্ট ব্লক ব্যতীত এর একই ব্যবহার হতে পারে, যেমন। (?: ($quantity -le 10) {.9} {.75})
ব্যবহারকারী 2864740

এটি দুর্দান্ত বৈশিষ্ট্যযুক্ত তবে এটি আপনার স্ক্রিপ্টটিকে অ-মানক হিসাবে রেন্ডার করতে পারে যেমন আপনার স্ক্রিপ্ট বা এর কিছু অংশ বন্দর নাও পারে যদি না এটির সাথে সংজ্ঞাটি পোর্ট করা না থাকে। আপনি মূলত এই মুহুর্তে আপনার নিজস্ব উপ-ভাষা তৈরি করছেন। এগুলি সমস্ত বর্ধিত জটিলতা এবং পাঠ্যতা হ্রাসের কারণে রক্ষণাবেক্ষণের ব্যয়কে বাড়িয়ে তুলতে পারে।
ভ্যানস ম্যাককর্কল

1
নিবন্ধন করুন কাস্টম টরেন্সনেস প্রায়শই কার্যকর হলে এর ব্যয় হয়। তবে পরিস্থিতি যদি খুব কমই ঘটে তবে আমি একটি "যদি" প্রকাশ করে থাকি।
এডওয়ার্ড ব্রে


21

আমিও, আরও উত্তরের জন্য সন্ধান করেছি এবং এডওয়ার্ডের পোস্টে সমাধানটি "ঠিক" থাকাকালীন আমি এই ব্লগ পোস্টে আরও অনেক প্রাকৃতিক সমাধান নিয়ে এসেছি

স্বল্প ও মধুর:

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

1
এটা বেশ দুর্দান্ত। আমি কেবল =ওরফে হিসাবে ব্যবহার পছন্দ করি না , কারণ ==সি # এবং অন্যান্য অনেক ভাষাতে সমতা যাচাইয়ের জন্য ব্যবহৃত হয়। সি # তে কিছু অভিজ্ঞতা থাকা পাওয়ারশেলরদের মধ্যে বেশ সাধারণ এবং এটি ফলাফলকে কিছুটা বিভ্রান্ত করে তোলে। :সম্ভবত একটি ভাল উপনাম হতে হবে। ভেরিয়েবল অ্যাসাইনমেন্টের সাথে এটি ব্যবহার করে =:কাউকে পাস্কলে ব্যবহৃত অ্যাসাইনমেন্টের কথা মনে করিয়ে দিতে পারে তবে ভিবি.এনট বা সি # তে কোনও তাত্ক্ষণিক সমতুল্য (যা আমি জানি) নেই।
nohwnd

আপনি যে কোনও উপন্যাসটি চান তা এটি সেট করতে পারেন। : বা ~যা যা আপনার নৌকাকে ভাসিয়ে দেয়। : ডি set-alias : Invoke-Assignment -Option AllScope -Description "FearTheCowboy's Invoke-Assignment." # $message =: ($age > 50) ? "Old Man" :"Young Dude" $message =: $foo ?? "foo was empty"
টেরিনারি

আমি জানি, এবং আমি করেছি, আমি কেন অন্য একটি উপাধ ব্যবহার করব তা মন্তব্য করছিলাম।
nohwnd

15

বিকল্প হিসাবে পাওয়ারশেলের সুইচ স্টেটমেন্টটি চেষ্টা করুন , বিশেষত ভেরিয়েবল অ্যাসাইনমেন্টের জন্য - একাধিক লাইন, তবে পঠনযোগ্য।

উদাহরণ,

$WinVer = switch ( Test-Path $Env:windir\SysWOW64 ) {
  $true    { "64-bit" }
  $false   { "32-bit" }
}
"This version of Windows is $WinVer"

1
এটি সামান্য আরও ভারবস হতে পারে, তবে অন্যান্য উত্তরগুলির অনেকের চেয়ে উল্লেখযোগ্য সুবিধা রয়েছে। বিশেষত, বাহ্যিক কোডের উপর কোনও নির্ভরতা নেই, বা কোনও স্ক্রিপ্ট বা মডিউলটিতে অনুলিপি / অনুলিপি করা হচ্ছে না।
bshacklett

9

যেহেতু একটি ট্রেনারি অপারেটর সাধারণত মূল্য নির্ধারণের সময় ব্যবহৃত হয়, তাই এটির একটি মান ফেরত দেওয়া উচিত। এটি এইভাবে কাজ করতে পারে:

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

বোকা, কিন্তু কাজ করছে। এছাড়াও এই নির্মাণটি দ্রুত কোনও মানকে অন্য একটি মান হিসাবে রূপান্তর করতে ব্যবহার করা যেতে পারে, কেবল অ্যারে উপাদান যুক্ত করুন এবং একটি অভিব্যক্তি নির্দিষ্ট করুন যা 0-ভিত্তিক অ-নেতিবাচক মানগুলি দেয়।


6
এটি বাম এবং ডান বিকল্পগুলির উত্সাহ-মূল্যায়নের জন্য বাধ্য করবে: এটি একটি সঠিক টার্নারি অপারেশন থেকে অনেক আলাদা।
ব্যবহারকারী 2864740

6

যেহেতু আমি এটি ইতিমধ্যে অনেকবার ব্যবহার করেছি এবং এটি এখানে তালিকাভুক্ত দেখতে পাইনি, আমি আমার টুকরো যুক্ত করব:

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

সব কদর্য!

কিন্ডা উত্স


4
এটি বাম এবং ডান বিকল্পগুলির উত্সাহ-মূল্যায়নের জন্য বাধ্য করবে: এটি একটি সঠিক টার্নারি অপারেশন থেকে অনেক আলাদা।
ব্যবহারকারী 2864740

@ ইউজার ২74077৪০ কারণ পিএসে কোনও সঠিক টের্নারি অপারেশন নেই। এটি একটি সিন্থেটিক বৈকল্পিক।
ভিগগো লন্ডন

2
@ ViggoLundén একটি সঠিক টের্নারি অপারেটরের অভাব মন্তব্যটির যথার্থতা হ্রাস করে না। এই "সিনথেটিক বৈকল্পিক" এর আলাদা আচরণ রয়েছে
ব্যবহারকারী 2864740

আপনি ঠিক বলেছেন, এবং আপনার মন্তব্যটি পুনরায় পড়ার পরে আমি বুঝতে পারি যে এটি কীভাবে সত্যিকারের পার্থক্য আনতে পারে। ধন্যবাদ।
সোডাওলো

5

আমি সম্প্রতি PoweSll lib 'Pscx' Pls- এ টেরিনারি কন্ডিশনাল এবং নাল-কোলেসিং অপারেটরগুলিকে উন্নত করেছি (ওপেন পুলরকুইস্ট)
আমার সমাধানটির সন্ধান করেছি।


আমার গিথুব টপিক শাখা: ইউটিলিটিমডুল_আইভোক-অপারেটর

কার্যাবলী:

Invoke-Ternary
Invoke-TernaryAsPipe
Invoke-NullCoalescing
NullCoalescingAsPipe

ওরফে

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"

ব্যবহার

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

<variable_expression> |?? <alternate_expression>

এক্সপ্রেশন হিসাবে আপনি পাস করতে পারেন:
ull নাল, একটি আক্ষরিক, একটি ভেরিয়েবল, একটি 'বাহ্যিক' এক্সপ্রেশন ($ বি-বেক 4) বা একটি স্ক্রিপ্ট ব্লক {$ বি-বেক 4}

যদি ভেরিয়েবলের এক্সপ্রেশনটিতে কোনও ভেরিয়েবল $ নাল হয় বা বিদ্যমান না থাকে বিকল্প বিকল্পটি আউটপুট হিসাবে মূল্যায়ন করা হয়।


4

পাওয়ারশেলের বর্তমানে একটি নেটিভ ইনলাইন ইফ নেই (বা ত্রৈমাসিক যদি ) তবে আপনি কাস্টম সেমিডলেট ব্যবহার করতে পারেন:

IIf <condition> <condition-is-true> <condition-is-false>
দেখুন: পাওয়ারশেল ইনলাইন যদি (IIf)


লিঙ্কযুক্ত পোস্টে একটি ফাংশন কীভাবে তৈরি করা যায় তা দেখানো IIfহয়। তবে, এখানে কোনও স্ট্যান্ডার্ড পাওয়ারশেল IIfফাংশন / সেমিডলেট নেই।
ব্যবহারকারী 2864740

1
@ ইউজার ২6464647৪০, তাহলে কী? এটি কি এই প্রশ্নের সম্ভাব্য ব্যবহারযোগ্য উত্তর হিসাবে উত্তরটিকে বাদ দিয়েছে: " একই ফলটি সম্পাদন করার সবচেয়ে ভাল উপায় (অর্থাত সহজভাবে পড়া এবং বজায় রাখা) কী হতে পারে?" কিন্তু যে সরাইয়া, লিঙ্ক IIf বোঝায় প্রশ্ন (পোস্ট সেপ্টেম্বর 5 '14) যে খুব এই (ডুপ্লিকেট?) অনুরূপ। লিঙ্কযুক্ত প্রশ্নের বাকী উত্তরগুলিও যুক্ত মান হিসাবে দেখা যেতে পারে (এবং যেখানে তা হয় না, এটি মূলত কারণ এটি নকল)।
আইআরন

কিছুটা ব্যাখ্যা অনেকদূর এগিয়ে যায়, এবং এ কারণেই কোনও অতিরিক্ত সংযুক্ত তথ্য না থাকলে নকলের জন্য বন্ধ না হওয়ায় খালি লিঙ্কগুলি নিরুৎসাহিত করা হয়। বিবেচনা করুন যে খুব ছোট ব্যাখ্যাটি এই জাতীয় খালি লিঙ্ক উত্তরের গুণমানকে উল্লেখযোগ্যভাবে বাড়িয়ে তুলবে : "পাওয়ারশেল সরাসরি 'টের্নারি' সমর্থন করে না (other তবে অন্যান্য উত্তরগুলি দেখুন) However তবে, কোনও ফাংশন যেমন (^ ব্যবহার করে) লেখা সম্ভব এই পদ্ধতিটি, বা অন্যান্য উত্তরগুলি দেখুন) .. ", তবে এটি যুক্ত করা আমার কাজ নয় । উত্তরগুলি প্রযোজ্য হিসাবে সংশোধন / আপডেট / ইত্যাদি হতে পারে।
ব্যবহারকারী 2864740

@ ব্যবহারকারী ২6464647৪০, আপনার মতামতের জন্য ধন্যবাদ, আমি সেই অনুযায়ী উত্তরে সামঞ্জস্য করেছি।
আইআরন

1

এখানে একটি বিকল্প কাস্টম ফাংশন পদ্ধতির:

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'

পার্থক্য ব্যাখ্যা

  • কেন এটি 1 এর পরিবর্তে 3 প্রশ্ন চিহ্ন?
    • ?চরিত্র ইতিমধ্যে একটি ওরফে হয় Where-Object
    • ?? নাল কোলেসেসিং অপারেটর হিসাবে অন্যান্য ভাষায় ব্যবহৃত হয় এবং আমি বিভ্রান্তি এড়াতে চেয়েছিলাম।
  • কমান্ডের আগে আমাদের পাইপের কী দরকার?
    • যেহেতু আমি পাইপলাইনটি এটির মূল্যায়নের জন্য ব্যবহার করছি তাই আমাদের ফাংশনটিতে শর্তটি পাইপ করার জন্য আমাদের এখনও এই চরিত্রটি প্রয়োজন
  • আমি যদি একটি অ্যারে পাস করি তবে কী হবে?
    • আমরা প্রতিটি মানের জন্য একটি ফলাফল পেতে; যেমন -2..2 |??? 'match' : 'nomatch'দেয়: match, match, nomatch, match, match(যেহেতু যেহেতু কোনও শূন্য-অন্তর্নিহিত মূল্যায়ন করে true; শূন্যের সাথে মূল্যায়ন করে false)।
    • যদি আপনি এটি না চান তবে অ্যারেটিকে একটি বিলে রূপান্তর করুন; ([bool](-2..2)) |??? 'match' : 'nomatch'(বা সহজভাবে [bool](-2..2) |??? 'match' : 'nomatch':)

1

আপনি যদি বুলিয়ান অবস্থার উপর ভিত্তি করে কোনও স্ট্রিং বা সংখ্যাটি নির্ধারণ / ফেরত দেওয়ার জন্য কেবল সিন্ট্যাক্টিক্যালি সহজ উপায়ের সন্ধান করেন তবে আপনি এই জাতীয় গুণটি অপারেটরটি ব্যবহার করতে পারেন:

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

যদি কোনও কিছু সত্য হওয়ার পরে আপনি যদি কেবলমাত্র ফলাফলটিতে আগ্রহী হন তবে আপনি কেবলমাত্র মিথ্যা অংশটি পুরোপুরি বাদ দিতে পারেন (বা বিপরীতে), যেমন একটি সাধারণ স্কোরিং সিস্টেম:

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

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

নোট করুন যে বুলিয়ান মানটি গুণণের ক্ষেত্রে শীর্ষস্থানীয় শব্দ হওয়া উচিত নয়, যেমন $ শর্ত * "সত্য" ইত্যাদি কাজ করবে না।


1

পাওয়ারশেল সংস্করণ 7 হিসাবে, টের্নারি অপারেটরটি পাওয়ারশেলের মধ্যে অন্তর্নির্মিত।

1 -gt 2 ? "Yes" : "No"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.