-join("$args"-split'\b'|%{(,$(,$_[0]*$n+$_))[!!($n=$($_-1))]})
Çevrimiçi deneyin!
Yıkmak
Ne dağınıklık!
Den başlayarak $args
RLE dizesini içeren tek bir öğe dizisi olan , ben tırnaklarını sararak gerçek bir dize zorlamak.
Sonra kelime sınırına bölün ( \b
normal ifade ile). Bu, her öğenin bir sayı veya sayıdan sonra gelen BF belirteçleri olduğu bir dizi dizeyi verecektir. Örnekte, bu bölünmüş dizinin ilk 4 unsurlarıdır Yani 10
, +]>+>
, 3
, +>
(bütün dizgi).
Sonra, bunu her öğeyle başa çıkmak için ForEach-Object
( %
) içine koyarım .
Orta, iyi bilinen bir PowerShell golfizmidir; aslında bir DIY üçlü operatörüdür, burada 2 elemanlı bir dizi oluşturup test etmek istediğiniz boolean ifadesini kullanarak dizine eklersiniz, böylece yanlış bir sonuç size element 0'ı verir ve gerçek bir sonuç size element 1'i verir.
Bu durumda, ,
gerçek durumda çıktı istemiyorum çünkü aslında tekli virgül operatörü ile tek bir öğe dizisi oluşturmak .
Önce, daha sonra çalıştırılsa bile dizinleyiciye bakalım.
Bunun fikri, $_
(geçerli öğe) geçerli bir sayı veya başka bir dize olabileceğidir. Bu bir sayı ise, $n
bu sayının eksi 1 (bir sayı olarak değil, bir dize) değeri olmak istiyorum . Değilse, $n
yanlış olmak istiyorum .
PowerShell genellikle sağ taraftaki değeri sol tarafın türüne zorlamaya çalışır, ancak işleme bağlı olabilir. Buna ek olarak, "10"+5
size yeni bir dize "105"
verirken 10+"5"
, size bir tamsayı ( 15
) verecektir .
Ancak dizeler çıkarılamaz, bu nedenle PowerShell, sayısal değeri çıkarma işleminin sol tarafındaki bir dize ile otomatik olarak çıkarabilir, bu nedenle "10"-5
verir 5
.
Yani, başlangıçta , aslında bir sayı $_-1
olduğunda istediğim numarayı verecek $_
, ama olmadığında hiçbir şey alamıyorum. Yüzeyde, "hiçbir şey" falseydir, ama sorun şu ki, o ödevin yürütülmesini durdurur, bu yüzden $n
önceki değerini korur; istediğim gibi değil!
Bir alt ifadeye sarırsam, başarısız olduğunda, falsey değerimi alırım: $($_-1)
.
Her şeyin atandığı $n
ve bu atamanın kendisi parantez içine alındığı için, atanan değer $n
de boru hattına aktarılır.
1
Dizin oluşturucuda kullandığım ve dönüşüm başarılı olursa istiyorum , ben bu değeri boole dönüştürmek için iki boolean- not
ifadeleri !!
kullanın. Başarılı bir sayı dönüşümü gerçek olarak sonuçlanırken, falsey hiçbir şey bize 0
o sahte üçlü dizideki tek öğeyi döndürmeye izin veren tatlı, tatlı verir.
Bu diziye geri dönersek, öğe şudur: $("$($_[0])"*$n*$_)
$(,$_[0]*$n+$_)
"$($_[0])"
- bu, geçerli öğenin ilk karakterini (diyelim ki, almak +
için +[>+
) almanın can sıkıcı uzun bir yoludur , ancak bir [char]
nesne olarak değil, bir dize olarak . Ben çoğaltmak için bir sayı ile bir dize çarpabilir, ancak bir karakter ile bunu yapamam çünkü bir dize olması gerekiyor.
Aslında [char]
(başka bir tek virgül kullanarak) bir dize yerine bir dizi kullanarak 4 karakter kaydetmeyi başardı ,
, bu yüzden tırnak ve ekstra alt ifade kaldırmak mümkün. Ben yapabilirsiniz öğelerini çoğaltmak için bir dizi çarpın. Ve bu yinelemenin tüm sonucu yine de bir dizi haline geldiğinden ve düzenlenmesi gerektiğinden -join
, burada bir dizi kullanmanın ek bir maliyeti yoktur.
Sonra, kez çoğaltmak için bu dize dizisi ile çarpın . Hatırlanacağı olabilir$n
$n
$n
$null
Önceki basamakların eksi bir değeri olabileceğini veya .
Ardından +$_
, geçerli öğeyi, o öğenin çoğaltılan ilk karakterinin sonuna ekler. Bu yüzden $n
eksi bir.
Bu şekilde, 10+[>+
birlikte biter $n
, o zaman 9 yapmak 9'a eşit +
'ın ve onu geri ekleyin +[>+
10 koşul artı gezinti için diğer tek öğeleri almak için dize.
Eleman, bir alt ifade sarılır $()
çünkü ne zaman $n
olduğunu $null
dizinleyici çalışır, böylece hiçbir tüm ifade, yani, başarısız şekilde dizi oluşturma başarısız $n
atanır olmadı.
Bu üçlü numara kullanılmaktadır nedeni onun özelliklerini birinin geçerli: Gerçek bir üçlü operatör aksine elemanlarını tanımlayan ifadeler do bu konuda ilk onlar "seçilmiş" olsun ya da olmasın değerlendirdi ve almak.
$n
Ayrı yinelemeler atamam ve sonra kullanmam gerektiğinden , bu yardımcı olur. Üçlü dizi öğesi değeri önceki yinelemenin $n
değeri ile değerlendirilir , ardından dizinleyici $n
geçerli yineleme için yeniden atar .
Böylece ForEach-Object
döngüler, olması gereken her şeyi (görmezden geldiğimiz bir grup hata) çıkarır, ancak yeni dizeler dizisi olarak sonuçlanır.
Böylece, her şey parantez içine alınır ve daha sonra -join
çıktı dizesini vermek için tekli kullanılır .