Поради щодо гольфу в PowerShell


45

Які загальні поради щодо гольфу в Windows PowerShell? Я шукаю ідеї, які можна застосувати до проблем із гольфом загалом, які принаймні дещо специфічні для PowerShell (наприклад, "видалити коментарі" - це не відповідь). Будь ласка, опублікуйте одну пораду за кожну відповідь.

—Взявся майже дослівно від запитання Маркога .


3
Коли я гугла "PowerShell golf", це був перший удар!
Метт

Відповіді:


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++){...}

проти

1..10|%{...}


18

Ви можете пропустити Прогалини багато в PowerShell. Якщо вам здається, що це може не знадобитися, то, можливо, це не так. Це особливо корисно для порівнянь.

Приклад:

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

vs.

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

Якщо вам потрібно розгалужувати сценарій за результатами одного тесту, який може мати декілька результатів, switchіноді може відповідати або перемогти оператор if.

Приклад (перем. На if / else - прив'язати):

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

vs.

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

Або (перем. На if / elseif / else - перемикач виграє на 15):

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

vs.

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

Якщо перемикач насправді заснований на певних математичних результатах, як-от операція з модулем, описаною вище, ви можете повністю замінити перемикач на масив. Тут він економить ще 13 символів і навіть коротший, ніж оригінальний двоскарочний оператор if / else. (Спасибі Данко Дурбіч за цей шматочок.)

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

Якщо ви будете багато використовувати певну команду, особливо одну, без попереднього псевдоніма короткої руки, на початку встановіть псевдонім з одним символом.

Приклад:

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

vs.

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

('even','odd')[$x%2]FYI.
TheIncorrigible1

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)
ПравописD

14

Комутатор може діяти як цикл, коли йому дано масив. Наприклад:

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

Виведе:

FOO
BAR
MEH

Я не зовсім впевнений, де це стане в нагоді, але сподіваюсь, що комусь це стане в нагоді деякий час.


2
Це зручно кожного разу, коли вам знадобиться ForEach-Objectі switchвсередині цього. Наприклад, код (в реальному світі) дуже приємний для написання швидких аналізаторів текстових файлів, де потрібно робити різні речі залежно від того, який регулярний вирівнювання відповідає рядку.
Joey

Це ... чорт дивно. Масив не повинен відповідати знаку, але це робить.
кіт

@Joey Ось що switch -File $pathє для
TheIncorrigible1

Не все, що розбирається, буває файлом.
Джої

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
Метт

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

Скорочення імен властивостей

На жаль, на відміну від параметрів, властивості / методи (все, до чого звертається з крапкою .) зазвичай не можуть бути скорочені до однозначної форми.

Але деякі командлети можуть працювати на іменах властивостей та отримувати групові символи, і є маловідомі набори параметрів з %і ?які можуть бути корисні.

Зазвичай ми передаємо в блоці сценаріїв і посилаємося на елемент з $_, але є інша форма, яка має ім'я властивості, і він приймає підстановку.

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

З таким властивістю, як .Lengthми не можемо використовувати магію v3, яка зазвичай працює на масиві, оскільки Lengthце властивість самого масиву, тому вищевказані два можна використовувати для отримання довжини окремих членів. selectПриходить трохи коротше.

Але %можна взяти ім’я властивості безпосередньо та повернути це значення:

$a|% Length

Які можна скоротити за допомогою макетів. Підстановочний знак повинен вирішувати одну властивість (або метод, про це пізніше пізніше), тому він видасть корисну помилку, якщо цього не зробить, вказуючи, які саме члени можуть вирішити.

У випадку 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оператор замінює регулярний вираз, але якщо ви просто робите заміну рядка, він може (тепер) коротше використовувати метод; це допомагає, що рядки є аргументами командлетів замість аргументів методу, тому їх не потрібно цитувати.

Де-Властивості об'єкта

?може також приймати (часткові) імена властивостей і застосовувати до нього "оператор" (у вигляді параметрів комутатора). Знову ж це може бути коротше , ніж при використанні стандартного Where-ObjectScriptBlock підходу , якщо ім'я властивості досить довго і унікальні.

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

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

1
Одне з небагатьох місць, де потрібен пробіл. Хороша знахідка, хоча. Я можу придумати кілька напрямків, де це скоротить речі.
AdmBorkBork

Приємна редакція Джої! Дякую.
британіст

Ви знайшли спосіб скоротити її ;-) ... сумно в тому, що в цілому це знову трубопровід, що трохи обмежує його корисність. А точніше, є багато місць, де вам доведеться знову загорнути його в дужки, щоб отримати вираз. Але кілька технік для гольфу без компромісів ...
Joey

1
@ConnorLSW ах, так, я мав намір оновити це так, як я зрозумів, що ви можете передавати аргументи таким чином, що значно підвищує його корисність. Велике використання .ToString()!
британіст

2
@briantist це перетворило PowerShell в набагато більш конкурентоспроможну мову, по-справжньому виключає деякі прикрослівні багатослівні виклики. Net.
colsw

9

Пошук суми довгим шляхом:

(...|measure -s).Sum

Коротший шлях:

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

І навіть коротше:

...-join'+'|iex

9

Точки з комою та перервами рядків взаємозамінні. Код для гольфу часто читається, якщо не застряг в одному рядку. А довжина все одно така ж (за умови використання U + 000A в якості розриву рядків, який PowerShell обробляє без проблем).


2
Зачекайте, ми переживаємо за читабельність ?!
Кевін Кокс

4
Якщо це не впливає на довжину ... чому б і ні?
Joey

Чи технічно це не має значення, оскільки крапка з комою на один символ менше, ніж \ r \ n? Тільки в Unix це однина \ n.
Василь Сіракіс

2
@Vasili: Ви можете просто зберегти файли, лише між U + 000A між рядками. PowerShell не скаржиться. Про що я вже писав у відповіді, до речі. Розриви рядків є властивістю файлу , а не операційної системи, на якій він використовується. Ніхто не каже, що не можна використовувати закінчення рядків Unix в Windows.
Джої

@Joey Якщо для швидкого програмування ви використовували свіжу інсталяцію Windows, ви помітите, що блокнот не грає добре з \ x0a
Stan Strum

9

GetДієслово мається на увазі. Це може скоротити будь-якого Get-Frobдо справедливого Frob. Частими претендентами є dateабо random.

Зауважте, що в деяких випадках це не спрацює належним чином, оскільки у вас можуть бути утиліти GNU на своєму шляху (або інші рідні програми, які зіштовхуються). Порядок пошуку команд у такому випадку, здається, віддає перевагу нативній програмі, перш ніж розглядати командлети зі 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сценарій зависає нескінченно (або, принаймні, потребує непомірної кількості часу на обробку - я не мав терпіння чекати, коли він закінчиться, але це займає на кілька порядків довше, ніж початкова форма перед тим, як перервати).
Іссі

2
Дві короткі Measure-Commandвиклики (100 разів Get-Randomпроти random) говорять мені, що це приблизно в 500 разів повільніше. Я цього раніше не знав, якщо чесно. Але добре пам’ятати про це, особливо в петлях з багатьма ітераціями. При цьому, код гольфу повинен бути коротким, а не швидким (але , як кажуть, достатньо чекати два дні, щоб відповісти на проблему Project Euler).
Джої

1
Моя проблема полягала у виконанні 10 000 ітерацій сценарію Monty Hall, кожна з яких потребувала трьох ітерацій Get-Random. Збільшення часу на обробку на 50 000%, помножене на 30 000 пробіг, досить неприємне.
Іссі

Ого. Схоже, те саме, ймовірно, справедливо і для будь-якого псевдоніма. Випробували Get-Variableпроти gvта отримали подібне порівняння.
Іссі

1
Це могло бути. Я зробив деяку математику і вважав, що мій сценарій Monty Hall повинен зайняти близько 1,5 годин (як правило, 10-11 секунд), щоб запустити без нього Get-. Це досить вродливий розквіт у часі роботи за економію всього 4 символів у довжину.
Іссі

8

for петлі можуть містити в своєму заголовку що-небудь між 0 і трьома заявами:

Нескінченний цикл:

for(){}

Цикл з ініціалізацією:

for($n=0){}

Цикл з ініціалізацією та кінцевою умовою:

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

У таких випадках додаткові крапки з комою в кінці можуть бути опущені (це чітко зазначено в специфікації мови , тому це не детальна інформація про реалізацію) на відміну від С-подібних мов, які завжди вимагають рівно трьох висловлювань.

Це також робить 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

vs.

"$x"

Передавання рядків подібним чином може також використовуватися для вирівнювання масиву рядків, а не приєднання до нього:

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

vs.

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

Передавання рядка до числового типу:

[int]$x     [float]$x

vs.

+$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, $ truthy результати беруть елемент 1:

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

NB. що це справді робить індексацію масиву, і якщо тест призведе до значення, яке може бути передано цілому числу, ви попросите елемент поза межами масиву і отримаєте $ null назад, і це потрібно буде зробити, !(test)щоб примусити киньте результат у булінг, при цьому параметри повернені.


Перший фрагмент не працював в один момент (старіші версії PowerShell), якщо я добре пам’ятаю, що робить його необхідним завершити $(). По суті, було розрізнення використання трубопроводів, зроблених з команд і висловлювань, як виразів. Здається, це вже минуло, принаймні в PowerShell 5.
Джої

Крім того, якщо елементи масиву нестатичні, обидва розбираються та обробляються як частина створення масиву до того, як відбудеться індексація, і результат буде призначений. Наприклад .
AdmBorkBork

6

Використовуючи число в якості аргументу для оператора, який інакше вимагатиме рядок, ви можете використовувати номер безпосередньо. Порівняйте

...-join'0'

vs.

...-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 спеціальну змінну, щоб змінити епіратор виводу F ield S, який використовується під час строфікації масиву. Корисно, якщо вам потрібно кілька разів перетворити масиви в рядки.

Наприклад:

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

Зберігає 2+ n символів на другому -join, де n - довжина роздільника, і зберігає додаткові 5+ n для 3-го -joinта кожного наступного.


1
На жаль, дуже рідко корисний (принаймні, в моєму гольфі до цих пір - я, як правило, позбавляю його лише одного приєднання в кінці).
Joey

5

Автоматичні змінні має булеві для істинного і помилкового , як $trueі $falseале ви можете отримати аналогічні результати з використанням логічного оператора не !та цілих чисел 0 і 1 (або будь-який ненульового числа.)

PS C:\Users\matt> !1
False

PS C:\Users\matt> !0
True

Майже всі вирази PowerShell можна оцінити як булеві. Тож, поки ви знаєте, як оцінюються певні дані, ви можете отримувати булеві символи і ніколи не потрібно їх чітко вводити. Будьте в курсі значення LHS, роблячи це.

  • Ціле число 0 є помилковим, а ненульові цілі числа оцінюються як істинні.
  • рядки з ненульовою довжиною є істинними, порожніми або нульовими (і самі нульові) рядки помилковими.

Є й інші приклади, але їх можна легко перевірити, виконавши ролі

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

1
Багато інших типів даних також мають подібний статус. Неініціалізовані змінні за замовчуванням $null, що є фальсі. Порожній рядок (і змінні, встановлені в порожній рядок) - фальси. І т.д. Це може бути використане для індексування ярликів у масив (наприклад, при виконанні if/ else), як це було використано в FizzBuzz .
AdmBorkBork

@TimmyD Дуже правда. Використання ints трохи коротше
Метт,

@TimmyD Я хотів відповісти на fizzbuzz, поки не побачив твого .... Не можу цього перемогти .... принаймні ще не
Метт

Зверніть увагу , що в багатьох випадках ви на самому ділі не потрібноbool . Ви можете використовувати 0і 1так само добре. Неявні перетворення дуже допомагають у цьому плані (що часто можна застосовувати у певних операторів).
Джої

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

vs.

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

2
Корисно для функцій, які не беруть аргументів. В іншому випадку, це params(...)займе більше місця, ніж економить визначення функції. Пов'язане: Використовуйте filterбільше, functionколи ви можете це зробити.
Joey

Ви можете використовувати, $argsщоб уникнути потреби params; тобто $x={$args[0]+2}(або навіть $x={2+"$args"}); може зберегти персонажа або 2 за деяких обставин. Ви також можете поєднати це з іншим трюком для кількох $x={$a,$b=$args;$a+$b+3}
парам

4

Ви можете використовувати $s|% t*yзамість того, [char[]]$sщоб розділити рядок на масив char. Даний з відповіді TessellatingHeckler : % t*yрозширюється до | ForEach-Object -Method ToCharArrayеквівалента. з"$args".ToCharArray()

Наприклад, порівняйте

$s|% t*y

і

[char[]]$s

і

$s.ToCharArray()

Це корисно $argsособливо:$args|% t*y


1
Це досить акуратно. Я %також декілька разів використовував трюк для членів, але більшість моїх гольфів передували цій функції ;-). Це також загальна техніка: Спробуйте знайти комбінацію букв / підстановку, яка відповідає властивості / методу, який вам потрібен (і коротший, ніж реальний).
Джої

Ще корисні приклади з відповіді: $s|% *perза $s.toUpper()і $s|% *werза $s.toLower(). Я згоден, це досить акуратно.
маззи

Ще один приклад : |% t* "ddd\:hh\:mm\:ss"для[TimeSpan].toString("ddd\:hh\:mm\:ss")
mazzy

Що ж, це просто марнотратство цитат; вам тут не потрібні :-)
Джої


3

Використовуйте логічну логіку замість лічильників if у циклі

Припустимо, ви додаєте всі парні числа від 1 до 10 ... 2+4+6+8+10=30

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

Ви можете використовувати булеве заперечення, щоб скоротити його

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

щоб зберегти байт, а як натомість використовувати неявну кастинг булевих форматів до ints та згортати умовне в акумулятор

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

Зберігає 6 байт у цьому прикладі.


2
Ісус Христос. Я планую це зробити у своєму виробничому коді на роботі, мої колеги будуть мене любити за це.
Чавес

3

Перетворення чисел з плаваючою комою в цілі числа в PowerShell - це трохи мінне поле. За замовчуванням конверсія робить " Округлення банкірів", яке не завжди обрізає десятковий і залишає менше ціле число, або завжди кругле .5 до наступного числа, як це роблять люди випадково; дивуватись, напр

PS C:\> [int]1.5
2

PS C:\> [int]2.5
2

і розбити розрахунки кодогольфа. Багато інших поширених мов виконують усічення, тому питання про гольф часто вимагають усічення. Ви можете досягти [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)також є зручним способом створення алфавіту
Веска
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.