เคล็ดลับสำหรับการเล่นกอล์ฟใน PowerShell


45

คุณมีคำแนะนำทั่วไปเกี่ยวกับการเล่นกอล์ฟใน Windows PowerShell อย่างไร ฉันกำลังมองหาแนวคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปซึ่งอย่างน้อยค่อนข้างเฉพาะกับ PowerShell (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ) กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ

-taken เกือบคำต่อคำจากคำถามของ marcog


3
เมื่อฉัน googled "PowerShell golf" นี่เป็นเพลงฮิตครั้งแรก!
Matt

คำตอบ:


24

พลังของ 10 ตัวอักษรที่มีเครื่องหมายทางวิทยาศาสตร์:

4e6 = 4000000

พลังของ 2 ตัวอักษร:

4KB = 4096
4MB = 4194304
4GB = 4294967296

# TB and PB suffixes also exist, but less useful for golf.

อาจมีประโยชน์


19

หากคุณจำเป็นต้องใช้ห่วงและคุณรู้ว่ากี่ครั้งก็ต้องใช้ทุกครั้งที่พิจารณาท่ออาร์เรย์ของจำนวนเต็มต่อเนื่องกันลงForEach-Objectผ่านนามแฝงแทนการใช้%for

for($x=1;$x-le10;$x++){...}

VS

1..10|%{...}


18

คุณสามารถข้ามช่องว่างมากมายใน PowerShell ถ้ามันรู้สึกว่ามันอาจไม่จำเป็น สิ่งนี้มีประโยชน์อย่างยิ่งในการเปรียบเทียบ

ตัวอย่าง:

$x-eq$i-and$x-ne9

เมื่อเทียบกับ

$x -eq $i -and $x -ne 9

หากคุณต้องการแยกสาขาสคริปต์ของคุณตามผลลัพธ์ของการทดสอบเดี่ยวซึ่งอาจมีหลายผลลัพธ์switchบางครั้งสามารถจับคู่หรือเอาชนะคำสั่ง if

ตัวอย่าง (สลับกับ if / else - tie):

if($x%2-eq0){'even'}else{'odd'}

เมื่อเทียบกับ

switch($x%2){0{'even'}1{'odd'}}

หรือ (สลับกับ if / elseif / else - สลับเป็นชนะ 15):

if($x%2-eq0){'even'}elseif($x%2-eq1){'odd'}else{'error'}

เมื่อเทียบกับ

switch($x%2){0{'even'}1{'odd'}2{'error'}}

สวิทช์เป็นจริงขึ้นอยู่กับผลทางคณิตศาสตร์บางอย่างเช่นมอดุโลข้างต้นคุณสามารถเปลี่ยนสวิทช์อย่างสิ้นเชิงกับอาร์เรย์ ที่นี่จะช่วยประหยัดอีก 13 อักขระและสั้นกว่าตัวเลือกสองตัวเลือก if / else (ขอบคุณDanko Durbicสำหรับบิตนี้)

('even','odd','error')[$x%2]

หากคุณจะใช้คำสั่งเฉพาะจำนวนมากโดยเฉพาะอย่างยิ่งคำสั่งที่ไม่มีชื่อแทนระยะสั้นที่มีอยู่แล้วให้ตั้งค่านามแฝงตัวอักษรตัวเดียวก่อน

ตัวอย่าง:

nal g Get-Random;g 10;g 10;g 10

เมื่อเทียบกับ

Get-Random 10;Get-Random 10;Get-Random 10

('even','odd')[$x%2]FYI
สิทธิ์ 1

15

การห่อหุ้มคำสั่งที่กำหนดตัวแปรในวงเล็บช่วยให้คุณสามารถป้อนคำจำกัดความของตัวแปรโดยตรงไปยังคำสั่งอื่น ๆ

ตัวอย่างเช่นคุณสามารถตั้งค่า $ x จากนั้นตั้งค่า $ y ตามค่าของ $ x ในนัดเดียวด้วยสิ่งนี้:

$y=($x=1)+1

แทนสิ่งนี้:

$x=1;$y=$x+1

คุณสามารถตั้งค่า $ h และเอาท์พุทด้วย:

($h='Hello World!')

แทนสิ่งนี้:

$h='Hello World!';$h

1
สิ่งนี้มีประโยชน์อย่างยิ่งสำหรับวิธีการเรียกใช้บนวัตถุ ($x=New-Object Windows.Forms.Form).Controls.Add($t)
SpellingD

14

สวิตช์สามารถทำหน้าที่เหมือนวนรอบเมื่อกำหนดอาร์เรย์ ตัวอย่างเช่น:

$FooBarMeh='a','b','c'
switch ($FooBarMeh)
{
    'a'{'FOO'}
    'b'{'BAR'}
    default{'MEH'}
}

จะส่งออก:

FOO
BAR
MEH

ฉันไม่แน่ใจว่าสิ่งนี้จะเป็นประโยชน์อย่างใด แต่ฉันคาดหวังว่ามันจะมีประโยชน์สำหรับบางคน


2
มันจะมีประโยชน์ทุกครั้งที่คุณต้องการForEach-Objectและswitchภายใน มันเป็นตัวอย่าง (ในโลกแห่งความเป็นจริง) รหัสดีมากสำหรับการเขียน parsers อย่างรวดเร็วของไฟล์ข้อความที่คุณต้องทำสิ่งต่าง ๆ ขึ้นอยู่กับว่า regex ตรงกับบรรทัด
Joey

นี่คือ ... อาร์เรย์ไม่ควรตรงกับถ่าน แต่เป็นเช่นนั้น
แมว

@ โจอี้นั่นคือสิ่งที่switch -File $pathมีไว้
TheIncorrigible1

ไม่ใช่ทุกสิ่งที่แยกวิเคราะห์เกิดขึ้นเป็นไฟล์
Joey

12

แทนที่[math]::powด้วยการคูณ แทน

[math]::pow($a,$b)

คุณสามารถเขียน

"$a*"*$b+1|iex

สิ่งนี้ใช้ได้สำหรับเลขชี้กำลังจำนวนเต็ม> = 0


ฉันต้องการเห็นคำตอบนี้เพื่อทำความเข้าใจiex... นามแฝงของInvoke-Expression
HeatfanJohn

11

ตัวดำเนินการเปรียบเทียบทำงานกับกลุ่มของค่าโดยส่งคืนค่าที่ตรงกัน:

1..5 -gt 2

จะให้ผลผลิต3, และ4 5ในบางกรณีสิ่งนี้สามารถช่วยให้ประหยัดได้นาน|?{$_...}ขึ้น

-match เป็นผู้ดำเนินการเปรียบเทียบด้วย


1
โปรดทราบว่าคุณไม่ต้องการช่องว่างในตัวอย่างนั้น1..5-gt2
Matt

1
ฉันรู้ว่า; นี่เป็นข้อมูลเพิ่มเติมเกี่ยวกับการแสดงเทคนิค ช่องว่างที่มีอยู่ในคำตอบที่แยกต่างหาก
Joey

11

ใช้นามแฝงทุกครั้งที่ทำได้ มีประโยชน์มากมาย

?        Where-Object
%        ForEach-Object
gu       Get-Unique
sort     Sort-Object
iex      Invoke-Expression

11

ต้องการค้นหาคอลเลกชันค่าสูงสุดหรือต่ำสุดหรือไม่? พยายาม

(...|measure -ma).Maximum

หรือ

(...|measure -mi).Minimum

แล้ว?

เพียงเรียงลำดับและใช้รายการสุดท้ายหรือรายการแรก:

(...|sort)[-1]  # maximum
(...|sort)[0]   # minimum

1
และถ้าคุณทราบความยาวของการรวบรวมค่าและมันน้อยกว่า 10 ...
wizzwizz4

@ wizzwizz4: โอ้ความยาวสูงสุดสามารถใช้งานได้อย่างสร้างสรรค์ไม่จำเป็นต้องเป็น 10 แม้ว่าสำหรับกรณีนี้ฉันไม่จำตัวอย่างที่ช่วยได้
Joey

1
ฉันหมายความว่าถ้ารายการสุดท้ายเป็นที่รู้จักกัน0, 1, 2, 3, 4, 5, 6, 7, 8หรือมันจะประหยัดไบต์เพื่อเขียนความยาวที่รู้จักกันแทน9 -1
wizzwizz4

10

การตัดทอนชื่อคุณสมบัติ

น่าเศร้าที่ไม่เหมือนพารามิเตอร์คุณสมบัติ / วิธีการ (สิ่งใดก็ตามที่เข้าถึงด้วยจุด.) ไม่สามารถย่อให้สั้นลงได้ในรูปแบบที่ชัดเจน

แต่ cmdlet บางอย่างสามารถทำงานกับชื่อคุณสมบัติและรับสัญลักษณ์แทนและมีชุดพารามิเตอร์ที่รู้จักกันน้อย%และ?มีประโยชน์

โดยปกติเราจะส่งผ่าน scriptblock และอ้างอิงถึงรายการด้วย$_แต่ก็มีรูปแบบอื่นที่ใช้ชื่อคุณสมบัติและยอมรับสัญลักษณ์แทน

$o|select Le*  
$o|%{$_.Length}

ด้วยคุณสมบัติเช่น.Lengthเราไม่สามารถใช้เวทย์มนตร์ v3 ที่ปกติจะทำงานกับอาเรย์เพราะLengthเป็นคุณสมบัติของอาเรย์เองดังนั้นทั้งสองข้างต้นสามารถใช้เพื่อรับความยาวของสมาชิกแต่ละคน selectมาในนิด ๆ หน่อย ๆ สั้น

แต่%สามารถใช้ชื่อคุณสมบัติได้โดยตรงและส่งคืนค่านั้น:

$a|% Length

ซึ่งสามารถย่อให้สั้นด้วย wildcard สัญลักษณ์แทนจะต้องแก้ไขเป็นคุณสมบัติเดียว (หรือวิธีการเพิ่มเติมในภายหลัง) ดังนั้นมันจะโยนข้อผิดพลาดที่เป็นประโยชน์หากไม่ได้ระบุว่าสมาชิกที่สามารถแก้ไขได้

ในกรณีของLength, Le*เป็นปกติที่สั้นที่สุด แม้ในสตริงเดียววิธีนี้จะสั้นกว่าเพียง 1 ไบต์โดยใช้คุณสมบัติ

$a.Length                # 9   #(doesn't work on array)
$a|%{$_.Length}          # 15
$a|% Le*                 # 8

แต่ขึ้นอยู่กับสิ่งที่คุณทำกับสิ่งนี้ คุณสามารถทำได้$a.Length*5แต่จะทำกับการแสดงออกของท่อที่คุณจะต้องห่อมัน($a|% Le*)*5; อาจยังคงคุ้มค่าถ้ามันเทียบกับอาร์เรย์ แต่ประเด็นคือมันไม่เหมาะสมเสมอไปที่จะทดแทน

มันทำงานร่วมกับวิธีการต่าง ๆ ได้เช่นกันและคุณสามารถละทิ้งสิ่ง()ที่ทำให้ชื่อเต็มมีความยาวเท่ากันได้ เมธอดต้องมีโอเวอร์โหลดที่ไม่มีพารามิเตอร์ (คุณสามารถส่งอาร์กิวเมนต์โดยวางไว้หลังชื่อเมธอดซึ่งดีมาก):

$a.ToUpper()             # 12
$a|% *per                #  9

ด้วยข้อโต้แย้ง:

'gaga'-replace'g','r'    # 21
'gaga'|% *ce g r         # 16

สิ่งเหล่านี้จะไม่เหมือนกันทุกประการซึ่ง-replaceผู้ประกอบการทำการแทนที่ regex แต่ถ้าคุณเพียงแค่ทำการแทนที่สตริงก็สามารถสั้นลงเพื่อใช้วิธีนี้ได้ ช่วยให้สตริงนั้นเป็นอาร์กิวเมนต์ cmdlet แทนที่จะเป็นวิธีการโต้แย้งดังนั้นจึงไม่จำเป็นต้องมีการเสนอราคา

คุณสมบัติของวัตถุ

?สามารถใช้ชื่อคุณสมบัติ (บางส่วน) ได้เช่นกันและใช้ "โอเปอเรเตอร์" กับมัน (ในรูปแบบของพารามิเตอร์สวิตช์) สิ่งนี้อาจสั้นกว่าการใช้Where-Objectวิธีการบล็อกสคริปต์มาตรฐานหากชื่อคุณสมบัติยาวพอและไม่ซ้ำกัน

$a|?{$_.Length-gt5}      # 19
$a|? Le* -GT 5           # 14

($a|% Le*)-gt5           # 14 - Lengths, not objs

1
หนึ่งในไม่กี่แห่งที่จำเป็นต้องมีช่องว่าง หาดีแม้ว่า ฉันสามารถนึกถึงหลาย ๆ พื้นที่ที่สิ่งนี้จะสั้นลง
AdmBorkBork

แก้ไขเป็นอย่างดี Joey! ขอบคุณ
ต้มตุ๋น

พบวิธีที่จะทำให้มันสั้นลง ;-) ... สิ่งที่น่าเศร้าเกี่ยวกับเรื่องนี้ก็คือมันเป็นท่ออีกครั้งซึ่ง จำกัด การใช้ประโยชน์ของมันเล็กน้อย หรือมีสถานที่มากมายที่คุณต้องห่อมันไว้ในวงเล็บอีกครั้งเพื่อให้ได้นิพจน์ แต่เทคนิคกอล์ฟไม่กี่อย่างที่ไม่มีการแลกเปลี่ยน ...
Joey

1
@ConnorLSW อ่าใช่ฉันตั้งใจจะอัปเดตสิ่งนี้เนื่องจากฉันรู้ว่าคุณสามารถผ่าน args ด้วยวิธีนี้ซึ่งเพิ่มประโยชน์อย่างมาก ใช้งานได้ดีมาก.ToString()!
นักเทศน์

2
@ ผู้ดำเนินการนี้ได้เปลี่ยน PowerShell เป็นภาษาที่แข่งขันได้มากขึ้นจริง ๆ แล้วลดการโทร. net
colsw

9

การหาผลรวมทางไกล:

(...|measure -s).Sum

วิธีที่สั้นกว่า:

...|%{$s+=$_};$s

และสั้นกว่า:

...-join'+'|iex

9

อัฒภาคและตัวแบ่งบรรทัดสามารถใช้แทนกันได้ รหัสที่ตีกอล์ฟมักจะอ่านได้ง่ายขึ้นหากไม่ติดขัดในบรรทัดเดียว และความยาวยังคงเหมือนเดิม (ให้คุณใช้ U + 000A เป็นตัวแบ่งบรรทัดที่ PowerShell จัดการได้โดยไม่มีปัญหา)


2
เดี๋ยวก่อนเรากังวลเกี่ยวกับการอ่านหรือไม่!
Kevin Cox

4
ถ้ามันไม่มีผลกับความยาว ... ทำไมล่ะ?
Joey

ในทางเทคนิคแล้วมันไม่ได้สร้างความแตกต่างเนื่องจากเซมิโคลอนนั้นมีตัวละครน้อยกว่า \ r \ n หรือไม่? เฉพาะในระบบ Unix เท่านั้นที่เป็นเอกพจน์ \ n
Vasili Syrakis

2
@Vasili: คุณสามารถบันทึกไฟล์ได้ดีเพียง U + 000A ระหว่างบรรทัด PowerShell จะไม่บ่น ซึ่งฉันเขียนไว้ในคำตอบแล้วโดยวิธี การแบ่งบรรทัดเป็นคุณสมบัติของไฟล์ไม่ใช่ของระบบปฏิบัติการที่ใช้ ไม่มีใครบอกว่าคุณไม่สามารถใช้ปลายสาย Unix บน Windows
Joey

@Joey หากคุณใช้การติดตั้ง windows ใหม่เพื่อทำการเขียนโปรแกรมอย่างรวดเร็วคุณจะสังเกตเห็นว่า Notepad ไม่เล่นกับ \ x0a ได้
ดี

9

Getกริยาบอกเป็นนัย ๆ นี้สามารถร่นใด ๆเพียงแค่Get-Frob Frobลุ้นบ่อยหรือdaterandom

โปรดทราบว่าสิ่งนี้จะไม่ทำงานอย่างถูกต้องในบางกรณีเพราะคุณอาจมีโปรแกรมอรรถประโยชน์ GNU ในเส้นทางของคุณ (หรือโปรแกรมอื่น ๆ ที่ขัดแย้งกัน) ลำดับของการค้นหาคำสั่งในกรณีนั้นดูเหมือนว่าต้องการโปรแกรมเนทีฟก่อนที่จะพิจารณา cmdlets ด้วยการGet-ลบออก:

PS Home:\> date

Freitag, 15. November 2013 07:13:45


PS Home:\> $Env:Path += ';D:\Users\Joey\Apps\GnuWin32\bin'
PS Home:\> date
Fr Nov 15 07:14:13 W. Europe Standard Time 2013

นี้ไม่ได้ค่อนข้างเสมอผลงานออกมาตามที่คาดไว้ ฉันมีสคริปต์ที่เริ่มต้นด้วยnal g Get-Randomการบันทึกตัวละครในภายหลัง การเปลี่ยนเป็นnal g Randomสาเหตุที่ทำให้สคริปต์หยุดไปเรื่อย ๆ (หรืออย่างน้อยใช้เวลาในการประมวลผลมากเกินไป - ฉันไม่ได้มีความอดทนรอให้มันสิ้นสุด ก่อนที่ฉันจะยกเลิก)
Iszi

2
การMeasure-Commandเรียกสั้นสองครั้ง (100 ครั้งGet-Randomเทียบกับrandom) บอกฉันว่าช้ากว่าประมาณ 500 เท่า ฉันไม่เคยรู้มาก่อนว่าจะซื่อสัตย์ แต่มันเป็นเรื่องดีที่จะจำไว้โดยเฉพาะในลูปที่มีการวนซ้ำหลายครั้ง ที่ถูกกล่าวว่ารหัส golfed ควรสั้นไม่เร็ว ( ที่กล่าวว่ามัน sucks ต้องรอสองวันสำหรับคำตอบสำหรับปัญหาโครงการออยเลอร์)
Joey

1
ปัญหาของฉันใช้10,000 สถานการณ์ของ Monty Hallแต่ละสถานการณ์ต้องมีการวนซ้ำสามครั้ง เวลาในการประมวลผลเพิ่มขึ้น 50,000% ซึ่งคูณด้วยการวิ่ง 30,000 ครั้งนั้นน่ารังเกียจ
Iszi

ว้าว. ดูเหมือนว่าเหมือนกันคงเป็นจริงสำหรับนามแฝงใด ๆ ทดสอบGet-Variableกับgvและมีการเปรียบเทียบที่คล้ายกัน
Iszi

1
นั่นอาจเป็นได้ ฉันไม่คณิตศาสตร์และคิดมอนตี้ฮอลล์สคริปต์ของฉันจะใช้เวลาประมาณ 1.5 ชั่วโมง (ปกติ 10-11 วินาที) Get-เพื่อทำงานได้โดยไม่ นั่นเป็นสิ่งที่น่าสังเกตในระยะเวลาอันสั้นเพื่อประหยัดเพียง 4 ตัวอักษร
Iszi

8

for ลูปสามารถมีอะไรก็ได้ระหว่าง 0 ถึงสามประโยคในหัวข้อ:

ห่วงที่ไม่มีที่สิ้นสุด:

for(){}

วนซ้ำกับการเริ่มต้น:

for($n=0){}

วนซ้ำกับเงื่อนไขการเริ่มต้นและสิ้นสุด:

for($n=0;$n-lt7){}

ในกรณีเช่นนี้อาจใช้เครื่องหมายอัฒภาคเพิ่มเติมในตอนท้าย (ซึ่งระบุไว้อย่างชัดเจนในข้อกำหนดภาษาดังนั้นจึงไม่ใช่รายละเอียดการใช้งาน) ซึ่งตรงกันข้ามกับภาษา C-like ซึ่งต้องมีสามข้อความเสมอ

ทำให้whileสั้นลงอีกเล็กน้อย เปรียบเทียบ

while(...){}

และ

for(;...){}

ด้วยโบนัสเพิ่มที่คุณสามารถติดในบรรทัดก่อนหน้า (ถ้ามี) ลงในช่องว่างforเช่นกันโดยไม่มีค่าใช้จ่ายเพิ่มเติม (และแม้กระทั่งการบันทึกอักขระ)


8

หากคุณกำลังกำหนดอาร์เรย์ที่คุณรู้ว่าจะมีเพียงสองค่าอย่าใช้การทำดัชนี

บางสิ่งเช่นนี้

$a="apple","orange"
$a[0] # apple
$a[1] # orange

สามารถเปลี่ยนเป็น:

$a,$o="apple","orange"
$a # apple
$o # orange

สิ่งนี้ยังมีประโยชน์หากคุณเพียงต้องการองค์ประกอบแรกของอาร์เรย์:

$a,$b=1..10
$a # 1
$b # 2..10

ในกรณีนี้ (พร้อมสตริง) $a="apple";$o="orange"ยาวเท่ากัน มันเป็นอาร์เรย์อีกต่อไปว่าบางครั้งสามารถปรับให้เหมาะสมเป็นธรรมอย่างเช่นโดยการวางองค์ประกอบทั้งหมดในสตริงที่มีตัวคั่นแล้วใช้-split(ที่ดีที่สุดที่จะใช้ช่องว่างเป็นตัวคั่นแล้วเพราะเอก-splitจะพอเพียง)
Joey

8

กำลังส่งสตริง:

[string]$x

เมื่อเทียบกับ

"$x"

การส่งไปที่สตริงเช่นนี้สามารถใช้เพื่อทำให้อาร์เรย์ของสตริงเรียบได้แทนที่จะเข้าร่วม:

$a = @('a','b','c')
$a -join ' '

เมื่อเทียบกับ

$a = @('a','b','c')
"$a"

การสตริสตริงเป็นชนิดตัวเลข:

[int]$x     [float]$x

เมื่อเทียบกับ

+$x

นอกจากนี้ยังมีประโยชน์มากที่จะรู้ว่า PowerShell เสมอใช้เวลาชนิดของตัวถูกดำเนินการทางด้านซ้ายเพื่อตรวจสอบชนิดสุดท้ายของการแสดงออกและการแปลงการสมัคร:

'1'+2    -> '12'
1+'2'    -> 3

ซึ่งสามารถช่วยพิจารณาว่ามีการปลดเปลื้องที่ไม่จำเป็น


6

อย่าลืมว่าคุณไม่จำเป็นต้องระบุชื่อเต็มของพารามิเตอร์เสมอและพารามิเตอร์บางตัวเป็นตำแหน่ง

Get-Random -InputObject (0..10)

... สามารถเล็มให้ ...

Get-Random -I (0..10)

... เพราะ "ฉัน" ในกรณีนี้ก็เพียงพอที่จะระบุInputObjectจากพารามิเตอร์ที่ถูกต้องอื่น ๆ สำหรับคำสั่งนี้

คุณสามารถตัดต่อไป ...

Get-Random (0..10)

... เพราะInputObjectเป็นพารามิเตอร์ตำแหน่ง

โดยทั่วไปแล้วการวางท่อจะสั้นกว่าการป้อนวัตถุเป็นพารามิเตอร์โดยเฉพาะอย่างยิ่งเมื่อสามารถลบความต้องการวงเล็บได้ ลองตัดตัวสร้างตัวเลขสุ่มของเราต่อไป ...

0..10|Get-Random

มองหาวิธีอื่นในการทำสิ่งเดียวกันแม้ว่าคุณจะไม่สามารถเปลี่ยนคำสั่งได้ สำหรับกรณีข้างต้นคุณสามารถทำสิ่งนี้:

Get-Random 11

หรือรวมคำแนะนำอื่น *:

Random 11

** หมายเหตุ: การละเว้นGet-จากชื่อคำสั่งสามารถขยายเวลาการทำงานได้ประมาณ 50,000% ไม่เลวถ้าคุณต้องการคำสั่งเพียงครั้งเดียว แต่ระวังการใช้มันในลูปแบบยาว *

และนั่นเป็นวิธีที่จะทำให้คำสั่งง่าย ๆ ลดขนาดลงเหลือหนึ่งในสามของขนาด


6

ผู้ประกอบการประกอบไปด้วยของปลอม คุณสามารถกำหนดโดยตรงจากifคำสั่ง:

$z=if($x-eq$y){"truth"}else{"false"}

แต่คุณสามารถใช้อาร์เรย์ 2 องค์ประกอบและใช้การทดสอบเพื่อทำดัชนี ผลการค้นหา $ falsey รับองค์ประกอบ 0 ผลการค้นหา $ จริงนำองค์ประกอบที่ 1:

$z=("false","true")[$x-eq$y]

NB ว่านี่คือการทำดัชนีอาเรย์จริงๆและหากผลการทดสอบมีค่าที่สามารถส่งไปยังจำนวนเต็มคุณจะขอรายการนอกขอบเขตของอาเรย์และรับ $ null กลับมาและจะต้องทำ!(test)เพื่อบังคับ ส่งผลลัพธ์ไปที่บูลโดยมีตัวเลือกย้อนกลับ


ข้อมูลแรกไม่ได้ทำงานที่หนึ่งจุดในเวลา (รุ่นเก่า PowerShell) $()ถ้าผมจำไม่ผิดทำให้จำเป็นต้องตัดมันลงไป โดยพื้นฐานแล้วมีความแตกต่างของการใช้ท่อที่ทำจากคำสั่งและข้อความเป็นนิพจน์ ดูเหมือนว่าตอนนี้จะหายไปอย่างน้อยก็ใน PowerShell 5
Joey

นอกจากนี้หากองค์ประกอบอาร์เรย์ไม่คงที่ทั้งได้รับการแยกวิเคราะห์และประมวลผลเป็นส่วนหนึ่งของการสร้างอาร์เรย์ก่อนที่จะเกิดการจัดทำดัชนีและผลที่ได้รับมอบหมาย เช่น
AdmBorkBork

6

เมื่อใช้ตัวเลขเป็นอาร์กิวเมนต์ให้กับโอเปอเรเตอร์ที่ต้องใช้สตริงคุณสามารถใช้ตัวเลขได้โดยตรง เปรียบเทียบ

...-join'0'

เมื่อเทียบกับ

...-join0

ใช้งานได้-splitดีเช่นกัน อาร์กิวเมนต์จะถูกแปลงเป็นสตริงก่อนเสมอ


สำหรับการอ้างอิงนี้ใช้ได้กับ-replaceเช่นกัน
AdmBorkBork

-replaceยังใช้งานได้โดยไม่มีข้อโต้แย้งที่สองที่คุณต้องการลบการแข่งขัน
Joey

5

ค่าสัมบูรณ์

กับ

$n=-123

แทน

[math]::abs($n)

ใช้

$n-replace'-'

แน่นอนว่าการออมจะถูกยกเลิกหากจำเป็นต้องใส่วงเล็บ


หรือถ้าคุณต้องการผลลัพธ์ทางด้านซ้ายของโอเปอเรเตอร์ ;-)
Joey

5

หากคุณต้องการเงียบข้อผิดพลาดตัวแปรที่ชัดเจนจะเป็น

try{ <# something that throws errors #> }catch{}

อย่างไรก็ตามวิธีนี้ยาวเกินไป ตัวแปรที่สั้นกว่าคือเรียกใช้tryบล็อกเป็นบล็อกสคริปต์และเพียงแค่เปลี่ยนเส้นทางข้อผิดพลาดไปยังตัวแปรที่ไม่ได้ตั้งค่า ( $nullอาจเป็นตัวแปรปกติ แต่ก็ยังยาวเกินไป):

.{ <# something that throws errors #> }2>$x

สิ่งนี้ช่วยประหยัดห้าไบต์ที่มีค่า (ถ้าไม่ใช่โลก)


5

ใช้$ofs ตัวแปรพิเศษที่จะเปลี่ยนO utput F ield S eparator ใช้เมื่อ stringifying อาร์เรย์ มีประโยชน์หากคุณต้องการแปลงอาร์เรย์เป็นสตริงหลายครั้ง

ตัวอย่างเช่น:

$a=1,2,3,4
$a-join',';$a-join','
$ofs=',';"$a";"$a"

บันทึกอักขระ2+ nตัวในวันที่ 2 -joinโดยที่nคือความยาวของตัวคั่นและบันทึกเพิ่มเติมอีก 5+ nสำหรับตัวที่ 3 -joinและแต่ละตัวหลังจากนั้น


1
น่าเสียดายที่ไม่ค่อยมีประโยชน์ (อย่างน้อยก็ในการเล่นกอล์ฟของฉันจนถึงตอนนี้ - ฉันมักจะตัดมันลงไปเพียงครั้งเดียวในตอนท้าย)
Joey

5

ตัวแปรอัตโนมัติมี booleans สำหรับ True และ False as $trueและ$falseแต่คุณสามารถรับผลลัพธ์ที่คล้ายกันได้โดยใช้ตัวดำเนินการเชิงตรรกะไม่ใช่!และจำนวนเต็ม 0 และ 1 (หรือจำนวนเต็มใด ๆ ที่ไม่ใช่ศูนย์)

PS C:\Users\matt> !1
False

PS C:\Users\matt> !0
True

ใกล้กับนิพจน์ PowerShell ทั้งหมดสามารถประเมินเป็นบูลีนได้ ดังนั้นตราบใดที่คุณทราบถึงวิธีการประเมินข้อมูลบางอย่างคุณจะได้รับ booleans และไม่จำเป็นต้องแปลงข้อมูลเหล่านั้นอย่างชัดเจน ระวังค่า LHS เมื่อทำสิ่งเหล่านี้

  • จำนวนเต็ม 0 เป็นเท็จและจำนวนเต็มไม่เป็นศูนย์จะถูกประเมินเป็นจริง
  • สตริงที่มีความยาวไม่เป็นศูนย์เป็นสตริงจริงและว่างเปล่าหรือสตริงว่าง (และ null เอง) เป็นเท็จ

มีตัวอย่างอื่น ๆ แต่คุณสามารถทดสอบได้ง่ายๆโดยการส่งนักแสดง

PS C:\Users\matt> [bool]@(0)
False

1
ประเภทข้อมูลอื่น ๆ อีกมากมายก็มีสถานะคล้ายกัน ตัวแปรที่ไม่ได้กำหนดค่าเริ่มต้น$nullคือซึ่งเป็นเท็จ สตริงว่าง (และตัวแปรที่ตั้งค่าเป็นสตริงว่าง) เป็นเท็จ ฯลฯ นี้จากนั้นจะสามารถใช้ในการจัดทำดัชนีลัดเป็นอาร์เรย์ (เช่นเมื่อทำif/ else) เช่นถูกใช้ในFizzBuzz
AdmBorkBork

@TimmyD จริงมาก การใช้ints สั้นลงเท่านั้น
Matt

@ TimmyD ฉันต้องการที่จะตอบ fizzbuzz จนกว่าฉันจะเห็นคุณ .... ไม่สามารถเอาชนะได้ .... อย่างน้อยยังไม่ได้
แมตต์

โปรดทราบว่าในหลายกรณีที่คุณไม่จริงต้อง boolคุณสามารถใช้0และ1เช่นกัน การแปลงโดยนัยช่วยได้มากในเรื่องนั้น (ซึ่งคุณสามารถบังคับใช้กับโอเปอเรเตอร์บางตัว)
Joey

4

Invoke-ExpressionและGet-Randomยังสามารถรับอินพุตไปป์ไลน์แทนการขัดแย้ง

สำหรับiexสิ่งนี้อนุญาตให้บันทึกวงเล็บในบางนิพจน์:

iex 1..5-join'+'   # won't work
iex(1..5-join'+')  # does work, but has extra parentheses
1..5-join'+'|iex   # doesn't need the parentheses

ในกรณีrandomนี้อนุญาตให้ใช้กรณีทั่วไปเพื่อปรับให้เหมาะสมเล็กน้อย:

random -mi 10 31   # gets a random integer between 10 and 30
10..30|random      # much better :-)
(random 21)+10     # if needed in another expression that doesn't require extra
                   # parentheses

วิธีหลังของการใช้มันเพียงแค่เลือกรายการจากรายการ -cอาร์กิวเมนต์จะได้รับการอนุญาตให้มากกว่าการเลือกเดียว


4

พิจารณาการจัดเก็บบล็อกสคริปต์ซ้ำในตัวแปรแทนที่จะใช้ฟังก์ชั่น

ฉันจะใช้สิ่งนี้เพื่อบันทึกตัวละครบางตัวในการนำไปใช้งาน Rock, Paper, Scissors ของฉันก่อนที่ฉันจะรู้ว่าการเขียนฟังก์ชันใหม่เป็นตัวแปรทำให้แม้แต่ตัวแปรไม่จำเป็น สิ่งนี้ยังคงมีประโยชน์สำหรับสคริปต์อื่น ๆ ซึ่งคุณใช้รหัสเดียวกันหลาย ๆ ครั้ง

function Hi{echo 'Hello, World!'};Hi

เมื่อเทียบกับ

$Hi={echo 'Hello, World!'};&$Hi

2
มีประโยชน์สำหรับฟังก์ชั่นที่ไม่รับอาร์กิวเมนต์ ไม่เช่นนั้นparams(...)จะใช้พื้นที่มากเกินกว่าที่คำจำกัดความของฟังก์ชันจะบันทึก ที่เกี่ยวข้อง: การใช้งานfilterมากกว่าfunctionเมื่อคุณสามารถทำเช่นนั้น
Joey

คุณสามารถใช้$argsเพื่อหลีกเลี่ยงความต้องการparams; เช่น$x={$args[0]+2}(หรือแม้กระทั่ง$x={2+"$args"}); อาจบันทึกอักขระหรือ 2 ในบางสถานการณ์ คุณยังสามารถรวมสิ่งนี้เข้ากับกลอุบายอื่น ๆ สำหรับ params หลายรายการ:$x={$a,$b=$args;$a+$b+3}
JohnLBevan

4

คุณสามารถใช้$s|% t*yแทน[char[]]$sการแบ่งสตริงเป็นอักขระอาร์เรย์ ได้รับจากคำตอบของ TessellatingHeckler : % t*yขยายเป็น| ForEach-Object -Method ToCharArrayequiv ของ"$args".ToCharArray()

ตัวอย่างเช่นการเปรียบเทียบ

$s|% t*y

และ

[char[]]$s

และ

$s.ToCharArray()

มันมีประโยชน์$argsโดยเฉพาะ:$args|% t*y


1
นั่นค่อนข้างเรียบร้อย ฉันใช้%เคล็ดลับสำหรับสมาชิกสองสามครั้งเช่นกัน แต่ส่วนใหญ่ของการเล่นกอล์ฟของฉันมีคุณสมบัตินั้น ;-) เป็นเทคนิคทั่วไปเช่นกัน: ลองค้นหาตัวอักษร / ชุดรวมที่ตรงกับคุณสมบัติ / วิธีที่คุณต้องการ (และสั้นกว่าของจริง)
Joey

อีกตัวอย่างที่มีประโยชน์จากคำตอบ: $s|% *perสำหรับ$s.toUpper()และสำหรับ$s|% *wer $s.toLower()ฉันเห็นด้วยที่ค่อนข้างเรียบร้อย
mazzy

อีกตัวอย่างหนึ่ง : |% t* "ddd\:hh\:mm\:ss"สำหรับ[TimeSpan].toString("ddd\:hh\:mm\:ss")
mazzy

นั่นเป็นเพียงคำพูดที่เสียไป คุณไม่ต้องการพวกเขาที่นี่ :-)
Joey


3

ใช้ตรรกะบูลีนแทนที่ if-counters ในลูป

สมมติว่าคุณกำลังเพิ่มจำนวนคู่ทั้งหมดตั้งแต่ 1 ถึง 10 ... 2+4+6+8+10=30

1..10|%{if($_%2-eq0){$o+=$_}};$o

คุณสามารถใช้การปฏิเสธบูลีนเพื่อย่อให้สั้นลง

1..10|%{if(!($_%2)){$o+=$_}};$o

เพื่อประหยัด byte แต่ใช้แทนการคัดเลือกโดยนัยของ Booleans ไปยัง ints และม้วนเงื่อนไขลงในตัวสะสม

1..10|%{$o+=$_*!($_%2)};$o

บันทึก 6 ไบต์ในตัวอย่างนี้


2
พระเยซู. ฉันวางแผนที่จะทำสิ่งนี้ในรหัสการผลิตในที่ทำงานเพื่อนร่วมงานของฉันจะรักฉัน
Chavez

3

การแปลงตัวเลขทศนิยมให้เป็นจำนวนเต็มใน PowerShell เป็นบิตของเขตที่วางทุ่นระเบิด โดยค่าเริ่มต้นการแปลงคือการปัดเศษของธนาคารซึ่งไม่ได้ตัดทศนิยมออกเสมอและปล่อยให้จำนวนเต็มน้อยลงหรือปัดเศษเป็น 0.5 เท่าจำนวนถัดไปเช่นเดียวกับที่คนทำกัน น่าแปลกใจเช่น

PS C:\> [int]1.5
2

PS C:\> [int]2.5
2

และทำลายการคำนวณ codegolf ภาษาทั่วไปอื่น ๆ อีกมากมายทำการปัดเศษการปัดเศษดังนั้นคำถามกอล์ฟมักจะต้องมีการตัดปลาย คุณอาจจะเอื้อมมือไปหา[Math]::Floor()สิ่งที่ดีที่สุดต่อไป แต่ระวังสิ่งนี้เท่านั้นที่จะทำงานเหมือนกับการตัดส่วนที่เป็นตัวเลขบวก แต่ใช้ตัวเลขลบต่ำกว่า - ห่างจากศูนย์ [Math]::Truncate()เป็นสิ่งที่คุณต้องนำมาซึ่งพฤติกรรมของ PS ให้สอดคล้องกับการปัดเศษภาษาอื่น แต่เป็นอักขระจำนวนมาก

Regex แทนที่ตัวเลขหลังจากจุดทศนิยมสามารถช่วยประหยัดอักขระได้สองตัว:

[Math]::Truncate(1.5)
[Math]::Floor(1.5)
1.5-replace'\..*'

[Math]::Truncate($a)
[Math]::Floor($a)
$a-replace'\..*'
$a.split('.')[0]        # literal character split, not regex pattern split

3

การย้อนกลับอาร์เรย์

มาพร้อมกับความสะดวกในความท้าทายของที่เอาท์พุทสะท้อนในแฟชั่นบางอย่าง

สมมติว่าคุณมี

$a=1,2,3,4,5

วิธีการกลับรายการแบบดั้งเดิมนั้นใช้เวลานานน่าเบื่อและไม่ทิ้งอาร์เรย์ไว้บนไปป์ไลน์เพื่อใช้งานได้ทันที

[array]::reverse($a)

การจัดทำดัชนีโดยตรงในอาร์เรย์ในลำดับย้อนกลับช่วยประหยัดสองสามไบต์เนื่องจากจะทิ้งผลลัพธ์ไว้ในไพพ์ไลน์ แต่ก็ยังค่อนข้างยาว:

$a[($a.count-1)..0]

ลองวนซ้ำแทน

$a|%{$a[-++$i]}

การจัดทำดัชนีย้อนกลับทำงานได้ดีเมื่อมีขอบเขตสูงสุดสำหรับการนับ
Joey

3

เริ่มต้นด้วย PowerShell Core 6 คุณยังสามารถใช้ช่วงสำหรับตัวละคร:

'a'..'z'

ซึ่งสามารถแทนที่ความยุ่งยากได้มากขึ้น

0..25|%{[char]($_+97)}

โอ้นี่จะเป็นประโยชน์อย่างมาก
AdmBorkBork

1
[char[]](65..90)ยังเป็นวิธีที่สะดวกในการสร้างตัวอักษร
Veskah
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.