Готовый перевод "D"iving Into the D Programming Language / Погружение в язык Ди: 1.4.3 Counting Frequencies. Lambda Functions
Давайте напишем ещё одну полезную программу, подсчитывающую число уникальных слов в тексте. Хотите узнать самые используемые слова в "Гамлете"? Вы в правильном месте!
Эта программа использует ассоциативный массив, отображая строки на uint и имеет такую же структуру, как и построитель словаря. Закончим программу, добавив простой цикл печати:
import std.stdio, std.string;
void main() {
// Compute counts
uint[string] freqs;
foreach (line; stdin.byLine()) {
foreach (word; split(strip(line))) {
++freqs[word.idup];
}
}
// Print counts
foreach (key, value; freqs) {
1.4. Arrays and Associative Arrays 13
writefln(" 9 56u\t 9 5s", value, key);
}
}
Отлично! Теперь, скачав hamlet.txt из сети (http: //erdani.com/tdpl/hamlet.txt), протестируем программу:
1 outface
1 come?
1 blanket,
1 operant
1 reckon
2 liest
1 Unhand
1 dear,
1 parley.
1 share.
Грустно, но этот вывод бесполезен - слова не отсортированы по частоте. Конечно, мы можем поступить проще - пропустить вывод через "sort -nr" (отсортировать числа в обратном порядке), но это хитрый трюк. Напишем сами сортировку, заменив последний цикл этим кодом:
// Print counts
string[] words = freqs.keys;
sort! ((a, b) { return freqs[a] > freqs[b]; }) (words) ;
foreach (word; words) {
writefln("%6u\ns" , freqs [word] , word) ;
}
Свойство .keys возвращает только ключи ассоциативного массива как массив строк. Массив создаётся отдельно в памяти, а нам это и нужно, ведь мы будем переставлять строки. Осталось разобрать код:
sort!((a, b) { return freqs[a] > freqs[b]; })(words);
Мы сразу же узнали шаблон, рассмотренный ранее:
sort!(<аргументы-времени-компиляции>)(<аргументы-времени-исполнения>);
Мы видим, что аргумент времени компиляции выглядит как недописанная функция, где забыли указать все типы и имя самой функции:
(a, b) { return freqs[a] > freqs[b] ; }
Это "лямбда" - короткая, безымянная функция, предназначение которой - передаваться в другие функции. Лямбды настолько часто применимы, что в Ди сделали всё возможное, чтобы избежать ненужного синтаксического мусора при её описании: типы параметров и возврата выводятся сами, не создавая неоднозначностей.
В этом примере стоит упомянуть ещё одну деталь, связанную с лямбдами: хотя переменная freqs - локальная для main, мы можем спокойно на неё ссылаться прямо из лямбды.
Вывод модифицированной программы:
929 the
680 and
625 of
608 to
523 I
453 a
444 my
382 in
361 you
358 Ham.
Как и ожидалось, наиболее общеупотребительные слова оказались первыми, за исключением "Ham" ("ветчина", прим.пер.). Это не говорит о кулинарных предпочтениях драмматического персонажа - это префикс всех цитат Гамлета. Кстати, их у него 358 штук - больше, чем у всех остальных. Если посмотреть далее, то следующий персонаж - король со всего лишь 116 строками. Офелия с её 58 цитатами вообще "молчунья"!
Внимание! Этот перевод, возможно, ещё не готов.
Его статус: идёт перевод
Переведено на Нотабеноиде
http://notabenoid.org/book/42515/189286
Переводчики: thornik
Настройки
Готово:
