URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID8
Нить номер: 891
[ Назад ]

Исходное сообщение
"Сложная сортировка хешей в Perl"

Отправлено Фдуч , 19-Ноя-02 15:40 
Люди помогите в решении возникшей проблемы!
есть хеш в котором хранится база по фильмам:
id ->num:::Name:::EnName:::Comment
то есть id - это ключ (уникальный идентификатор записи в массиве)
НУЖНО сделать сортировку по номеру, по названию (по алфавиту), по EnglishName по алфавиту.....
Проблема в том, что никак не могу понять как в условие сортировки включить регулярное выражение вычисляющее необходимое поле из строки значения записи хеша....

foreach $key (sort ByAge keys(%ages)) {
}

sub ByAge {
    $ages{$a}<=>$ages{$b}; # вот как сюда вписать регулярное выраж.?
}


Содержание

Сообщения в этом обсуждении
"RE: Сложная сортировка хешей в Perl"
Отправлено uldus , 19-Ноя-02 19:38 
>Проблема в том, что никак не могу понять как в условие сортировки
>включить регулярное выражение вычисляющее необходимое поле из строки значения записи хеша....

Пример из жизни:
foreach $key (reverse sort
             { ($info{$a}[0]*10 + $info{$a}[1]) <=> ($info{$b}[0]*10 + $info{$b}[1]) }
             keys %info){
....
}


"RE: Сложная сортировка хешей в Perl"
Отправлено Фдуч , 26-Ноя-02 16:58 
Спасибо за отклик!
К сожалению не совсем понял принцип действия твоего примера :(((
у меня вот какая задача:
есть хешь вот такой структуры:
ID => Number:::Name:::EnglishName:::Date
Пример:
128 => 100:::Матрица:::Matrix:::12/08/2001

Что касается сортировки по номеру (поле "Number")все просто:
foreach $id (sort{$disk{$a}<=>$disk{$b}} keys %disk)

А вот по имени (поле "Name") немного сложнее необходимо в сортировку включить регулярное выражение которое отсекало бы из значения все кроме поля Name :

foreach $id (sort{$disk{$a} cmp ($disk{$b}=~/.*:::[.*]:::/)} keys %disk){
Вот тут то я и обос*ался....
Что то там сортируется но что и как!???...
Очень прошу, подскажите как это сделать правельно?



"RE: Сложная сортировка хешей в Perl"
Отправлено uldus , 27-Ноя-02 10:38 
>есть хешь вот такой структуры:
>ID => Number:::Name:::EnglishName:::Date
>Пример:
>128 => 100:::Матрица:::Matrix:::12/08/2001

Используй массив, а не строчное представление.

$hash{ID}[0]= 100;
$hash{ID}[1]="Матрица";
$hash{ID}[2]="Matrix"
$hash{ID}[3]="12/08/2001";


"RE: Сложная сортировка хешей в Perl"
Отправлено Фдуч , 27-Ноя-02 18:07 
Замечательно! Я был очень обрадован такой возможностью хранения данных как массивы в хеше!!!! Однако увы....
В перле есть замечательная возможность хранения хешей в dbm-файлах - имеющих структуру файлов баз данных, чем я успешно и пользовался:
Запись в базу:
dbmopen(%disk, $tdisk, 0644) || die "Ошибка DBM-файла $tdisk: $!";
$disk{$id}= $number.":::".$name.":::".$ename.":::".$state.":::".$date;
dbmclose(%disk);
Чтение из базы:
dbmopen(%disk, $tdisk, 0644) || die "Ошибка DBM-файла $tdisk: $!";
$_ =$disk{$id};
($number,$name,$ename,$state,$date) = split(/:::/);
dbmclose(%disk);
В данном случае все прекрасно, за исключением известных проблемм с сортировкой по отдельным полям....

Так вот самое обидное!!!!!!!!:
dbmopen(%disk, $tdisk, 0644) || die "Ошибка DBM-файла $tdisk: $!";
$disk{1}[0]="Matrix";
dbmclose(%disk);
**************************************
%disk=();
**************************************
dbmopen(%disk, $tdisk, 0644) || die "Ошибка DBM-файла $tdisk: $!";
$result = $disk{1}[0];
dbmclose(%disk);
# $result НЕ равен "Matrix"
:(((((((((
то есть выходит, что замечательная возможность хранения хешей в dbm-файлах не работает для хешей массивов??????

или я ошибаюсь?


"RE: Сложная сортировка хешей в Perl"
Отправлено uldus , 28-Ноя-02 14:10 
>В перле есть замечательная возможность хранения хешей в dbm-файлах - имеющих структуру

Для DBM можно так:

foreach $key (reverse sort
             { (split(/\:\:\:/, $info{$a})[2]) cmp (split(/\:\:\:/, $info{$b})[2])) }
             keys %info){
....
}


"RE: Сложная сортировка хешей в Perl"
Отправлено Konst , 15-Дек-02 15:24 
СОРТИРОВКА ВНУТРИ ХЭША!
======
...
$hash{1} = 'aaa:::ppp:::zzz:::92';
$hash{2} = 'bbb:::ddd:::sss:::3';
$hash{3} = 'ccc:::kkk:::nnn:::77';

sub sss {
#   $field = shift; (НЕ РАБОТАЕТ)
    $field = $ARGV[0]; # по какому полю сортировать!
    @a = split('::+',$hash{$a});
    @b = split('::+',$hash{$b});
#    $a[$field] cmp $b[$field];
#    ИЛИ
### если надо круче - то =>
    if ($a[$field] =~ /^\d+$/ && $b[$field] =~ /^\d+$/) {
    $a[$field] <=> $b[$field];
    } else {
    uc($a[$field])  cmp  uc($b[$field]);
    }
###
}

print "SORT=$ARGV[0]\n";
foreach $x (sort sss keys %hash) {
    print "$x ($hash{$x})\n";
}
# РАБОТАЕТ!!!
# НО КТО-БЫ ПРИДУМАЛ КАК ПЕРЕДАВАТЬ АРГУМЕНТ foreach $x (sort sss($sort_key)   keys %hash) {