Perl 6圣誕月歷 (2014)

2014


Data munging in Perl 6 vs Perl 5


案例學習: 生成成績報告單

example.txt
STDOUT
Peter   B
Celine  A-
Zsófia  B+
Jo?o    F
Maryam  B+
秀英  B-
Finn    D+
Aarav   A
Emma    F
Omar    B

輸出報告單:

Zsófia's grade: B+
List of students with a failing grade:
  Jo?o, Emma
Distribution of grades by letter:
  A: 2 students
  B: 5 students
  D: 1 student
  F: 2 students

example.txt 是一個文本文件, 每行一個學生姓名和分數(shù)效五,中間用空格分割据德。
我們希望我們的腳本能解析這樣的文件并打印含有如下信息的報告:

學生名為 “Zsófia”的成績
所有不及格學生的名字 (i.e. worse than D-),
根據(jù)字母( 不帶 +/- ) 把成績分組办桨。得到學生成績的分布僵驰。
讓我們一步步來:

Part 1: 樣板

Perl 5

#!/usr/bin/env perluse warnings;
use strict;use feature 'say';
use utf8;
binmode STDOUT, ':utf8';

Perl 6

#!/usr/bin/env perl6

在 Perl 6 中所有這些都為我們做好了就斤。

Part 2: 讀取并解析輸入

Perl 5

open my $fh, '<:utf8', "grades.txt"
    or die "Failed to open file: $!";
my %grade;
while (<$fh>) {
    m/^(\w+) \s+ ([A-F][+-]?)$/x
        or die "Can't parse line '$_'";
   $grade{$1} = $2;
};

Perl 6

my %grade = "grades.txt".IO.lines.map: {
   m:s/^(\w+) (<[A..F]><[+-]>?)$/
        or die "Can't parse line '$_'";
    ~$0 => ~$1
};

在 Perl 6 中充边, 對文件名字符串調(diào)用 .IO 方法會返回一個代表文件系統(tǒng)路徑的對象庸推, 我們可以繼續(xù)在這個對象上調(diào)用 .lines 方法,得到文件的所有行的一個惰性列表浇冰。 “Lazy” 意味著它只會從磁盤中按需讀取新行贬媒,當我們使用 .map 方法遍歷列表元素的時候, 這樣能使用單個賦值操作就能優(yōu)雅地初始化一個散列肘习。
我們不需要讓文件句柄識別 Unicode 际乘,也不用管文件句柄是否正確關(guān)閉, 這在 Perl 6 中都是默認發(fā)生的漂佩。
.method: ... 語法也可以寫為 .method(...), 前者使 map 看起來更像一個 block 語句脖含,并減少了括號凌亂。
:s (“sigspace”) 正則修飾符使解析 tokens 間的空白更優(yōu)雅投蝉。 但 Perl 6 中的字符類比 Perl 5 復雜了一丟丟养葵。
正則捕獲結(jié)果變量($0, $1, …) 返回一個完整的 Match 對象 - 它為復雜使用場景增加了很多靈活性, 但是這里我們只想保留字符串瘩缆, 所以使用 ~ 前置操作符字符串化了匹配對象关拒。

Part 3: 查看數(shù)據(jù)的特定項

Perl 5

say "Zsófia's grade: $grade{Zsófia}";

Perl 6

say "Zsófia's grade: %grade<Zsófia>";

Perl 6 總是把散列中的 { } 中的東西解析為表達式, 使用 < > 表示字面值庸娱。

Part 4: 過濾數(shù)據(jù)

Perl 5

say "List of students with a failing grade:";
say "  " . join ", ",  grep { $grade{$_} ge "E" } keys %grade;

Perl 6

say "List of students with a failing grade:";
say "  " ~ %grade.grep(*.value ge "E")?.key.join(", ");

Perl 6 中允許我們按執(zhí)行順序把一些列方法寫為鏈式操作着绊。有一個重要區(qū)別:Perl 6 能讓我們直接遍歷散列的項, 散列中每一項都是一個 Pair 對象(Pair 對象能使用 .key 和.value 方法)涌韩。

The * Whatever star 用于定義一個簡單的回調(diào)畔柔,而不用寫一個花括號塊。
The ?. hyper operator 用于對 .grep 返回的 Pairs 的每個 Pair 上調(diào)用 一次 .key 方法臣樱,得出姓名列表

Part 5: 從數(shù)據(jù)中創(chuàng)建頻率分布

Perl 5

say "Distribution of grades by letter:";
my %freq;
$freq{substr $grade{$_}, 0, 1}++ for keys %grade;
say "  $_: $freq{$_} student".($freq{$_} != 1 ? "s" : "")    for sort keys %freq;

Perl 6

say "Distribution of grades by letter:";
say "  {.key}: {+.value} student{"s" if .value != 1}"
    for %grade.classify(*.value.comb[0]).sort(*.key);

計數(shù)和分組實在太常見了靶擦, Perl 6 提供了 .classify 方法腮考。
classify 方法里需要指定要分組的項(這里是 代表 %grade 條目的 Pair 對象 ), 這些項應該根據(jù)什么規(guī)則進行分組(這里是根據(jù)第一個字母的值玄捕, 它代表分數(shù)(沒有 +/-))踩蔚。
這生成一個匿名的散列,散列的值是匿名數(shù)組枚粘。

%("B" => ["Peter" => "B", "Zsófia" => "B+", "Maryam" => "B+",
 "秀英" => "B-", "Omar" => "B"],  "A" => ["Celine" => "A-", "Aarav" => "A"],  "F" => ["Jo?o" => "F", "Emma" => "F"],  "D" => ["Finn" => "D+"])

因為我們只對每組元素的個數(shù)感興趣馅闽, 我們使用 + 前置操作符數(shù)字化每個值然后打印它, 在數(shù)組前面添加 + 符號會得到數(shù)組元素的個數(shù)馍迄。
在 term 位置上一個 單獨的 .method 方法等價于 $_.method, 意思是對當前循環(huán)變量調(diào)用該方法福也。
任意代碼的返回值能使用花括號 {} 插值到字符串中。
if 語句能被用作表達式 - 當條件為 false 時攀圈,返回空列表暴凑,然后被字符串化為空字符串。
對字符串調(diào)用不帶參數(shù)的 .comb 會生成該字符串的一個字符列表赘来。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末现喳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子犬辰,更是在濱河造成了極大的恐慌嗦篱,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件幌缝,死亡現(xiàn)場離奇詭異灸促,居然都是意外死亡,警方通過查閱死者的電腦和手機狮腿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門腿宰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缘厢,你說我怎么就攤上這事∷Υ欤” “怎么了贴硫?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長伊者。 經(jīng)常有香客問我英遭,道長,這世上最難降的妖魔是什么亦渗? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任挖诸,我火速辦了婚禮,結(jié)果婚禮上法精,老公的妹妹穿的比我還像新娘多律。我一直安慰自己痴突,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布狼荞。 她就那樣靜靜地躺著辽装,像睡著了一般。 火紅的嫁衣襯著肌膚如雪相味。 梳的紋絲不亂的頭發(fā)上拾积,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音丰涉,去河邊找鬼拓巧。 笑死,一個胖子當著我的面吹牛一死,可吹牛的內(nèi)容都是我干的肛度。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼摘符,長吁一口氣:“原來是場噩夢啊……” “哼贤斜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起逛裤,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瘩绒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后带族,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锁荔,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年蝙砌,在試婚紗的時候發(fā)現(xiàn)自己被綠了阳堕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡择克,死狀恐怖恬总,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情肚邢,我是刑警寧澤壹堰,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站骡湖,受9級特大地震影響贱纠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜响蕴,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一谆焊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浦夷,春花似錦辖试、人聲如沸辜王。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽誓禁。三九已至,卻和暖如春肾档,著一層夾襖步出監(jiān)牢的瞬間摹恰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工怒见, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留俗慈,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓遣耍,卻偏偏與公主長得像闺阱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子舵变,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容