Perl 6 .rotor - 列表操作之王

Perl 6 .rotor - The King of List Manipulation

對(duì)于 Perl 6 程序員, .rotor是一個(gè)強(qiáng)大的列表操作工具。

分段


最簡(jiǎn)單的, .rotor接收一個(gè)整數(shù)$number并把列表分成多個(gè)子列表, 每個(gè)子列表含有 $number 個(gè)元素:

say <a b c d e f  g h>.rotor: 3
# ((a b c) (d e f))

我們有一個(gè)含有 8 個(gè)元素的列表, 我們?cè)谠摿斜砩险{(diào)用接收參數(shù) 3 的 .rotor方法, 它返回 2 個(gè)列表, 每個(gè)列表中含有 3 個(gè)元素。不包括原列表中的最后 2 個(gè)元素, 因?yàn)樗鼈儧]有組成一個(gè)完整的3個(gè)元素的列表。然而它們可以被包含進(jìn)來(lái), 使用 :partial具名參數(shù)設(shè)置為 True:

say <a b c  d e f  g h>.rotor: 3, :partial
# ((a b c) (d e f) (g h))

say <a b c  d e f  g h>.rotor: 3, :partial(True)
# ((a b c) (d e f) (g h))

say <a b c  d e f  g h>.rotor: 3, :partial(False)
# ((a b c) (d e f))

下面應(yīng)用一下我們剛剛學(xué)到的。把字符串分成列寬相等的幾段:

"foobarberboorboozebazmeow".comb.rotor(10, :partial)?.join?.say
# foobarberb
# oorboozeba
# zmeow

分行然后每行前面添加 4 個(gè)空格:

"foobarberboorboozebazmeow".comb.rotor(10, :partial)>>.join>>.indent(4)>>.say
#    foobarberb
#    oorboozeba
#    zmeow

但是這最好被寫為:

"foobarberboorboozebazmeow".comb(10)?.say

注意縫隙


假設(shè)你正在接受輸入: 你得到一個(gè)單詞, 它的法語(yǔ)翻譯和它的西班牙語(yǔ)翻譯, 等一堆單詞。你只想輸出特定語(yǔ)言, 所以我們需要在我們的列表中跳過(guò)某些項(xiàng)。 .rotor來(lái)拯救來(lái)了!

指定一對(duì)兒(Pair)整數(shù)作為 rotor 的參數(shù)會(huì)讓每個(gè)列表中含有 $key 個(gè)元素, 每個(gè)列表之間有 $value 個(gè)空隙。看例子更簡(jiǎn)單一些:

say ^10 .rotor: 3 => 1, :partial
>>>OUTPUT: ((0 1 2) (4 5 6) (8 9))
say ^10 .rotor: 2 => 2, :partial
>>>OUTPUT: ((0 1) (4 5) (8 9))

第一個(gè)例子我們把縫隙設(shè)置為 1, 第二個(gè)例子我們把縫隙增加為 2。

enum <English French Spanish>;
say join " ", <Good Bon Buenos morning matin días>[French..*].rotor: 1 => 2;
>>>OUTPUT: Bon matin

其中 [French..*]意思為 [1..*], 例子中 French 被枚舉化為整數(shù) 1。

重疊


當(dāng)我們讓縫隙變?yōu)樨?fù)數(shù)的時(shí)候, 分段的列表中就會(huì)有元素重疊:

say <a a b c c c d>.rotor: 2 => -1
>>>OUTPUT: ((a a) (a b) (b c) (c c) (c c) (c d))
say <a a b c c c d>.rotor(2 => -1).map: {$_[0] eq $_[1] ?? "same" !! "different"}
>>>OUTPUT: (same different different same same different)

全力以赴


.rotor不單單只能接受單個(gè) Int 值或 Pair, 你可以指定額外的 IntPairs 位置參數(shù)來(lái)把列表分成不同尺寸大小的子列表, 列表之間的縫隙也不同。下面以一個(gè)日志文件為例:

IP: 198.0.1.22
Login: suser
Time: 1454017107
Resource: /report/accounting/x23gs
Input: x=42,y=32
Output: success
===================================================
IP: 198.0.1.23
Login: nanom
Time: 1454027106
Resource: /report/systems/boot
Input: mode=standard
Output: success

每段之間有一行雙劃線。

我們想這樣輸出: Header 里包含 IP, Login, Time, Resource; Operation 里包含 Resource, Input, Output。

for 'report.txt'.IO.lines?.indent(4).rotor( 4 => -1, 3 => 1 ) -> $head, $op {
    .say for "Header:",    |$head,
             "Operation:", |$op, '';
}

>>>OUTPUT:
    Header:
        IP: 198.0.1.22
        Login: suser
        Time: 1454017107
        Resource: /report/accounting/x23gs
    Operation:
        Resource: /report/accounting/x23gs
        Input: x=42,y=32
        Output: success

    Header:
        IP: 198.0.1.23
        Login: nanom
        Time: 1454027106
        Resource: /report/systems/boot
    Operation:
        Resource: /report/systems/boot
        Input: mode=standard
        Output: success

先是 4 個(gè)元素一塊, 縫隙為 -1(有重疊), 然后是 3 個(gè)元素一塊, 縫隙為 1。這就在每個(gè)分段的列表中包含了 Resource 字段。因?yàn)?$op$head是列表, 我們使用管道符號(hào) |來(lái)展平列表。

記住, 你提供給 .rotor方法的模式可以動(dòng)態(tài)地生成! 這兒我們使用 sine 函數(shù)來(lái)生成:

say ^92 .rotor(
    (0.2, 0.4 ... 3).map: (10 * *.sin).Int # pattern we supply to .rotor
).join: "\n"'
>>>OUTPUT:
    0
    1 2 3
    4 5 6 7 8
    9 10 11 12 13 14 15
    16 17 18 19 20 21 22 23
    24 25 26 27 28 29 30 31 32
    33 34 35 36 37 38 39 40 41
    42 43 44 45 46 47 48 49 50
    51 52 53 54 55 56 57 58 59
    60 61 62 63 64 65 66 67 68
    69 70 71 72 73 74 75 76
    77 78 79 80 81 82
    83 84 85 86 87
    88 89 90
    91

再舉個(gè)例子:

我現(xiàn)在想要將同類的序列(字符串)進(jìn)行合并,比如有這樣一個(gè)文件:

>seq-1A
GACACAGTCACCCGAGCCT
>seq-1B
TCAATCAATACTGAAGCGA
>seq-1C
AAAACTAGTCGAGAAGAGAG
>seq-1D
CGTGGAAAACTCCAG
>seq-2A
TAAAAGGCGTTCATTGGATATTTC
>seq-2B
ACTGGCAGTGCATCC

我想要進(jìn)行合并 得到這樣的結(jié)果:

>seq-1
GACACAGTCACCCGAGCCTTCAATCAATACTGAAGCGAAAAACTAGTCGAGAAGAGAGCGTGGAAAACTCCAG
>seq-2
TAAAAGGCGTTCATTGGATATTTCACTGGCAGTGCATCC

使用 rotor 來(lái)實(shí)現(xiàn):

use v6;

my %re;
for 'input.txt'.IO.lines?.rotor(2, :partial) -> $header, $data {
    my $key = $header;
    $key ~~ s/<upper>$//;
    %re{$key} ~= $data;
}

for %re.kv -> $key, $value {
    say "$key\n$value";
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 問(wèn)答題47 /72 常見瀏覽器兼容性問(wèn)題與解決方案? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 14,144評(píng)論 1 92
  • 從匹配中返回值 Match 對(duì)象 成功的匹配總是返回一個(gè) Match 對(duì)象, 這個(gè)對(duì)象通常也被放進(jìn) $/ 中, (...
    焉知非魚閱讀 1,937評(píng)論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評(píng)論 19 139
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,798評(píng)論 11 349
  • 1.Xcode的報(bào)錯(cuò) a.library not found for -lPods-AFNetworking 錯(cuò)誤...
    brilliance_Liu閱讀 369評(píng)論 0 0

友情鏈接更多精彩內(nèi)容