Perl 6 .rotor - 列表操作之王

Perl 6 .rotor - The King of List Manipulation

对于 Perl 6 程序员, .rotor是一个强大的列表操作工具。

分段


最简单的, .rotor接收一个整数$number并把列表分成多个子列表, 每个子列表含有 $number 个元素:

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

我们有一个含有 8 个元素的列表, 我们在该列表上调用接收参数 3 的 .rotor方法, 它返回 2 个列表, 每个列表中含有 3 个元素。不包括原列表中的最后 2 个元素, 因为它们没有组成一个完整的3个元素的列表。然而它们可以被包含进来, 使用 :partial具名参数设置为 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))

下面应用一下我们刚刚学到的。把字符串分成列宽相等的几段:

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

分行然后每行前面添加 4 个空格:

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

但是这最好被写为:

"foobarberboorboozebazmeow".comb(10)».say

注意缝隙


假设你正在接受输入: 你得到一个单词, 它的法语翻译和它的西班牙语翻译, 等一堆单词。你只想输出特定语言, 所以我们需要在我们的列表中跳过某些项。 .rotor来拯救来了!

指定一对儿(Pair)整数作为 rotor 的参数会让每个列表中含有 $key 个元素, 每个列表之间有 $value 个空隙。看例子更简单一些:

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))

第一个例子我们把缝隙设置为 1, 第二个例子我们把缝隙增加为 2。

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

其中 [French..*]意思为 [1..*], 例子中 French 被枚举化为整数 1。

重叠


当我们让缝隙变为负数的时候, 分段的列表中就会有元素重叠:

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不单单只能接受单个 Int 值或 Pair, 你可以指定额外的 IntPairs 位置参数来把列表分成不同尺寸大小的子列表, 列表之间的缝隙也不同。下面以一个日志文件为例:

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 个元素一块, 缝隙为 -1(有重叠), 然后是 3 个元素一块, 缝隙为 1。这就在每个分段的列表中包含了 Resource 字段。因为 $op$head是列表, 我们使用管道符号 |来展平列表。

记住, 你提供给 .rotor方法的模式可以动态地生成! 这儿我们使用 sine 函数来生成:

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

再举个例子:

我现在想要将同类的序列(字符串)进行合并,比如有这样一个文件:

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

我想要进行合并 得到这样的结果:

>seq-1
GACACAGTCACCCGAGCCTTCAATCAATACTGAAGCGAAAAACTAGTCGAGAAGAGAGCGTGGAAAACTCCAG
>seq-2
TAAAAGGCGTTCATTGGATATTTCACTGGCAGTGCATCC

使用 rotor 来实现:

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";
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,754评论 1 92
  • 从匹配中返回值 Match 对象 成功的匹配总是返回一个 Match 对象, 这个对象通常也被放进 $/ 中, (...
    焉知非鱼阅读 1,800评论 0 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,672评论 18 139
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,255评论 11 349
  • 1.Xcode的报错 a.library not found for -lPods-AFNetworking 错误...
    brilliance_Liu阅读 353评论 0 0