![]() |
|
Модераторы: korob2001, ginnie |
![]()
|
|
| Suppir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Добрый день!
Есть хеш с ключами вида: Закон Краснодарского края от 01.05.2010 N 1370-кз Закон Краснодарского края от 02.05.2010 N 1371-кз Постановление губернатора Краснодарского края от 01.05.2010 N 456 Постановление губернатора Краснодарского края от 01.05.2010 N 457 Приказ департамента здравоохранения от 07.03.2009 N 12 Приказ департамента здравоохранения от 07.01.2009 N 2 Мне нужно перебрать этот хеш с сортировкой: foreach $x(sort sSort (keys %hash)){ print "$x\n"; } sub sSort{ # здесь нужна функция сортировки } я могу отсортировать даты вида 01.01.2010 и 02.03.2009: sub sorDate{ $hash{$a}{date} =~ /(\d+)\.(\d+)\.(\d+)/; $c = $3.$2.$1; $hash{$b}{date} =~ /(\d+)\.(\d+)\.(\d+)/; $d = $3.$2.$1; $d <=> $c; } Однако мне нужно сделать сортировку строк вида "Закон Краснодарского края от 01.05.2010 N 1370-кз" следующим образом: 1) в первую очередь учитывается текст до даты (сортировка по алфавиту - $a cmp $b) 2) потом сортировка по дате (однако по номеру нужно сравнивать с помощью $a <=> $b) Можно ли объединить два вида сортировки: cmp и <=> в одной функции сортировки? Спасибо. |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: нет Всего: 260 |
так же, как вычленяешь даты, вычлени и остальные параметры сравнения. и воспользуйся тем, что <=> возвращает 0, если элементы равны. и используй оператор "или": ||
как-то так:
|
|||
|
||||
| Suppir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Спасибо, попробую!
|
|||
|
||||
| Suppir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Работает!
только мне кажется, что работает чуть помедленней, чем если сделать сортировку два раза: первый раз по алфавиту, второй раз по дате. Потому что если делать сортировку два раза, то используются более короткие регулярные выражения. |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: нет Всего: 260 |
я рад. на Perl никогда не писал привет. если второй раз делать сортировку по дате, то функция пересортирует весь массив по дате, а не только те элементы, где имя совпадает. это ж совсем другое. длина регулярки не имеет значения. а имеет значение сложность. кстати, ты одной регуляркой разбиваешь на части, или для вытягивания каждой части ты натравливаешь разные регулярки в отдельности? в Perl должно быть, но я без опыта это уже не нашел, такая вещь, как компиляция регулярного выражения. Что позволяет сделать разбор регулярки только раз. Если тебя так напрягает скорость - выясни этот момент. лучше бы проверить чем-то. не поверю, что под Perl нет инструментов профилирования, что приходится рассчитывать только на "кажется" |
|||
|
||||
| Suppir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Вот так стала выглядеть функция сортировки:
sub smartSort{ $hash{$a}{type} =~ /(\S+)\s(.+)? от (\d+)\.(\d+)\.(\d+)/; $stype1= $1.$2.$1; $sdate1 = $5.$4.$3; $hash{$b}{type} =~ /(\S+)\s(.+)? от (\d+)\.(\d+)\.(\d+)/; $stype2 = $1.$2.$1; $sdate2 = $5.$4.$3; $stype1 cmp $stype2 || $sdate2 <=> $sdate1 } Это сообщение отредактировал(а) Suppir - 18.7.2010, 11:29 |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: нет Всего: 260 |
нормально работает?
|
|||
|
||||
| Suppir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Да вроде работает
|
|||
|
||||
| ming |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 97 Регистрация: 30.1.2009 Где: Новосибирск Репутация: 2 Всего: 3 |
попробуйте к регуляркам добавить модификатор "о" для их прекомпиляции. Вдруг немного ускорит?
$hash{$a}{type} =~ /(\S+)\s(.+)? от (\d+)\.(\d+)\.(\d+)/o; $hash{$b}{type} =~ /(\S+)\s(.+)? от (\d+)\.(\d+)\.(\d+)/o; |
|||
|
||||
| Suppir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
ming, замерил бенчмарком - скорость ровно такая же. Но, в принципе, на сортировку уходит не так много времени - около минуты.
|
|||
|
||||
| KSURi |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Регулярные выражения, которые не содержат внутри себя переменных компилируются автоматически.
-------------------- Died at Life.pl line 21 |
|||
|
||||
![]()
|
| Правила форума "Perl" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |