Готовый перевод "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

Настройки

Готово:

100.00% КП = 1.0