Создание серверных приложений на языке PERL

Сортировки


Сортировка хэша:

%hash = (

'шляпа' => 'серая',

'водка' => 'горькая',

'вобла' => 'вкусная');

foreach $key(sort keys %hash){

print "$key => $hash{$key}\n"; #отсортирует в алфавитном порядке по значениям ключа

}

foreach $value(sort values %hash){

print "$value\n"; #сортировка по значению

}

Сортировка ключей по алфавиту ассоциированных значений:

foreach $key(sort {$hash{$a} cmp $hash{$b}} keys %hash){



print $key, " => ", $hash{$key},"\n";

}

Сортировка по длинне ассоциированных значений:

@massive = sort{length($hash{$a}) length($hash{$b})}

keys %hash;

foreach $key(@massive){

print $key, $hash{$key},"\n";

}

Пример из fido7.ru.perl:

>> Есть хеш массив (слово, частота), необходимо вывести в файл пары

>> (слово,частота) отсортированные по частоте. По ключю - просто, а вот

>> по значению затрудняюсь. Подскахите как проще сделать?

my %hash=('for'=>1000,'to'=>1500,'in'=>2000,'do'=>500);

foreach(sort {$hash{$a} $hash{$b}} keys %hash) {

print $_,'=',$hash{$_},"\n";

}

Как можно хеш положить в строку? Например проблема:

tnc> имеются логи http-gw. Плохость их

tnc> заключается в том, что на каждый запрос в логе появляется 4 строки,

tnc> совершенно не обязательно идущие подряд:

Создаешь хэш и держишь в нем те строчки, которые еще, грубо говоря,

не закрыты, а как закроешь - удаляй. Конечно, некий заметный кусок

файла в памяти будет присутствовать, но не полностью же.

Что-нибудь типа

while(<IN>) {

($key, $no, $data) = parse($_); # расковыряли строчку

$buf{$key}-<[$no] = $data; # запихнули в хэш в виде массива

next if $no > 3; # нумеруем, ессно с нуля

analyze($buf{$key}); # обработали

delete $buf{key}; # удалили

}

Слияние хешей выполняется как и слияние массивов:

%hash1 = (

'шляпа' => 'серая',

'водка' => 'горькая',

'вобла' => 'вкусная');

%hash2 = (

'штаны' => 'широкие',

'пиво' => 'темное',

'игрушка' => 'любимая');


%allhash = (%hash1, %hash2);

Чтобы сэкономить память, можно воспользоваться таким кодом:

%hash=();

while (($key, $values) = each(%hash1)){

$hash{$key} = $values;

}

while (($key, $values) = each(%hash2)){

$hash{$key} = $values;

}

Пример работы с хэшем и базой данных из fido7.ru.perl (cм. ответ):

VS> Скажите, можно ли ввести в dbm-базу данных уже заполненный значениями

VS> хеш? Если да, то как?

%hash1=("dfadf", "dfadfd");

dbmopen (%hash, "hash", 0666);

%hash=%hash1;

dbmclose (%hash);

Как передать хэш в функцию? fido7.ru.perl (см. всю дискуссию)

> PK> Вобщем то все передаеться, но использовать его нельзяю

> PK> Hа %_[0] или $_[0]{??} компилер ругаеться.

> %a;

> &f(\%a);

> sub f {

> my $a = $($_[0]){'key'};

> }

> кажется так, мог ошибится в написании. Смысл в передаче ссылки, а не значения.

Это можно сделать также:

1. Неявной передачей ссылки (использование прототипов):

sub f(\%) {

my $a=$_[0]->{'key'};

}

f(%a);

2. Передачей хэша как массива с четным числом

элементов:

sub f {

my $a={@_}->{'key'};

}

f(%a);

Пример использования хеша для транслитерации fido7.ru.perl:

RK> Как сочнить такой tr/../../ (и возможно ли), чтобы

RK> "аб я" -> "abyoya"

RK> Т.е. транслитерацию сделать...

самый простой и топорный вариант - сделать хеш

с соответствиями типа я => ya сплитить строчки и заменять элементы

полученного массива на нужные. что-то на подобие:

@letters = split //, $str;

for (@letters){$_ = $hash{$_}};


Содержание раздела