Girişinizde çift sayıda öğe var:
say elems <1 1 0 2 0 2 1 2 2 2 4 4 3 3>; # 14
Kişisel grepbloğu iki öğe her zaman tüketir:
{$^a eq $^b}
Dolayısıyla, bir öğe ekler veya kaldırırsanız, blok sonunda kalan tek bir öğe üzerinde çalıştırıldığında karşılaştığınız hatayı alırsınız.
Sorununuzu çözmenin birçok yolu vardır.
Ancak aynı zamanda üst üste binmeye izin verme seçeneğini de sordunuz; örneğin, (2 2)sekansla 2 2 2karşılaşıldığında iki alt liste alırsınız . Ve benzer bir şekilde, muhtemelen sıfır olmayan iki eşleşme görmek istiyorsunuz, giriş gibi:
<1 2 2 3 3 4>
Bu yüzden bu sorunlarla da ilgilenen çözümlere odaklanacağım.
Ekstra sorunlarla başa çıkmak için çözüm alanının daralmasına rağmen, çözümleri işlevsel olarak ifade etmenin hala birçok yolu vardır.
Sonuna biraz daha kod eklemenin bir yolu:
my @s = <1 1 0 2 0 2 1 2 2 2 4 4 3 3>;
say grep {$^a eq $^b}, @s .rotor( 2 => -1 ) .flat
.rotorYöntem, alt-listeleri, aynı uzunlukta, her bir listesini gösteren bir listeyi dönüştürür. Örneğin, say <1 2 3 4> .rotor: 2görüntüler ((1 2) (3 4)). Uzunluk bağımsız değişkeni bir çiftse, anahtar uzunluktur ve değer sonraki çifti başlatmak için bir ofsettir. Ofset negatifse alt liste çakışması alırsınız. Böylece say <1 2 3 4> .rotor: 2 => -1görüntülenir ((1 2) (2 3) (3 4)).
.flatYöntem "derecede düzeltilir" onun invocant. Örneğin, say ((1,2),(2,3),(3,4)) .flatgörüntüler (1 2 2 3 3 4).
Yukarıdaki çözümü yazmanın belki de daha okunabilir bir yolu, tarafından döndürülen alt listelerin çıkarılması flatve kullanılması .[0]ve .[1]dizine eklenmesi olacaktır rotor:
say @s .rotor( 2 => -1 ) .grep: { .[0] eq .[1] }
Ayrıca herhangi bir alt liste boyutu için genelleştirilen başka bir varyasyon için Elizabeth Mattijsen'in yorumuna bakın.
Daha genel bir kodlama desenine ihtiyacınız varsa aşağıdaki gibi bir şey yazabilirsiniz:
say @s .pairs .map: { .value xx 2 if .key < @s - 1 and [eq] @s[.key,.key+1] }
.pairsBir listedeki bir yöntem çiftlerinin bir listesini, kendi invocant listesindeki elemanlarının her birine tekabül eden her bir çift döner. .keyHer bir çiftin invocant listedeki elementin endeksidir; .valueelemanın bir değerdir.
.value xx 2yazılabilirdi .value, .value. (Bkz xx.)
@s - 1@seksi 1'deki eleman sayısıdır .
[eq]İçinde [eq] listbir olduğunu azalma .
Bitişik eşit öğeleri neyin oluşturduğuna karar vermek için metin deseni eşleşmesine ihtiyacınız varsa, giriş listesini bir dizeye dönüştürebilirsiniz, eşleşme listesi oluşturan eşleşme zarflarından birini kullanarak eşleştirin, ardından sonuçtaki eşleşme listesinden istediğiniz eşlemeyle eşleştirin sonuç. Çakışanlarla eşleşmek için (örn 2 2 2. ((2 2) (2 2))Kullanımdaki sonuçlar :ov:
say @s .Str .match( / (.) ' ' $0 /, :ov ) .map: { .[0].Str xx 2 }
2 2 2 23(2 2)s yazdırır . Yöntemi hiç duymadımrotorBaşlangıçta yönteme geldimsquishve bunun gibi özelliklere veya argümanlara sahip olup olmadığını kontrol ettim,@s.squish(:length 2, :multiple_instances yes)ancak bu tür özelliklere sahip değildi ve görev için uygun değildi. İle karşılaştırıldığındasquish,rotoroldukça uygun görünüyor. Aslında bu tür bir işlem için en uygun olanı bile olabilir.