Forum Webscript.Ru

Программирование => Perl => Тема начата: AnnA от 02 Июля 2004, 12:42:41

Название: сортировка хэша
Отправлено: AnnA от 02 Июля 2004, 12:42:41
:insane:
Ребятки, дорогие, научите сортировать хэш, а? рази навсегда. :confused:
бьюсь-бьюсь с этой заразой, что-то никак у меня "не выходит каменный цветок".
отсортировать да потом еще и на печать бы вевести...
стыдно сказать - перегоняю в массив, сортирую как нужно, да и печатаю.

  001 цифра1|цифра2|цифра3|цифра4|буквы|цифра5
key^

Как сортировать по key понятно. ;) А вот как отсотрировать это, например по "цифра4" - не знаю. :(
пробовала по всякому. что-то даже получалось но при этом куда-то пропадали значения по которым сортируешь.
Вот, например, в таком хэше есть скажем 40 записей, нужно его отсртировать и вывести в банальную html таблицу.
сейчас я вот как делаю:

while (($ky, $ve) = each (%HASH)) {
   my ($tt,$m,$d,$h,$rr,$w)=split (/\\|/,$ve);
   my ($r,undef) = split(/\\|/,$Remark{$ky});
   push (@cnt,join(\'|\', $ky,$r,$tt,$m,$d,$h,$rr,$w,"\\n"));
 }
@cnt=sort $data @cnt;

$data получаю из строки запроса. в данном случае это "bymnt"

sub bymnt { my $mnta=(split(/\\|/,$a))[3]; my $mntb=(split(/\\|/,$b))[3]; return ($mntb <=> $mnta); }
Название: сортировка хэша
Отправлено: NeoNox от 02 Июля 2004, 13:06:15
perldoc -q sort
Название: сортировка хэша
Отправлено: AnnA от 02 Июля 2004, 14:15:51
хороший ответ. "разбирайся сама".
оставлю как есть.
и на том спасибо.
Название: сортировка хэша
Отправлено: NeoNox от 02 Июля 2004, 14:21:41
AnnA ответ замечательный - там все как на лодоне. или ты мне предлагаешь за тебя написать?
Название: сортировка хэша
Отправлено: AnnA от 02 Июля 2004, 14:46:55
NeoNox для Вас, может и на "лодоне". и потом, я же сказала "спасибо". Нет, не прдлагаю. Не нужно за меня ничего писать. На той ладони нет нужного мне примера кода из которого я уже дальше разобралась бы во всем сама. Ну или он есть, но я его просто не вижу.
Название: сортировка хэша
Отправлено: NeoNox от 02 Июля 2004, 15:31:46
у тебя в каждом элементе только пять значений?
Название: сортировка хэша
Отправлено: AnnA от 02 Июля 2004, 15:43:13
нет. ошиблась. на самом деле только 6!
в каждом элементе только шесть значений.
Название: сортировка хэша
Отправлено: NeoNox от 02 Июля 2004, 15:51:24
посмотри вот это
Цитировать
%h = (
       001 => ["one", "two", "three"],
       002 => ["four", "five", "six"]
     );

foreach my $key (sort { $h{$a}[1] cmp $h{$b}[1] } keys %h){
    print "$key = $h{$key}[1] \\n";
}

здесь структуру я намеренно упростил.
надеюсь дописать под себя несложно будет?
(здесь сортировка идет по второму значению $h{$a}[1])
Название: сортировка хэша
Отправлено: AnnA от 02 Июля 2004, 18:27:25
ничего себе "упростил"! :)
while (($ky, $ve) = each (%SH)) {
   
   ($tt,$m,$d,$h,$rr,$w)=split (/\\|/,$ve);
   ($r,undef) = split(/\\|/,$R{$ky});
  %h = ( $ky => [$r,$tt,$m,$d,$h,$rr,$w] );
#$ky = 001 до 100

# %h{"$ky"}=["$r", "$tt", "$m", "$d", "$h", "$rr", "$w"];
#при такой записи вообще выдается ошибка компилякии

 }


foreach my $key (sort { $h{$a}[1] cmp $h{$b}[1] } keys %h){
print "$key = $h{$key}[1] \\n";
}


на печать идёт одна строка. последняя. всего их ровно 100.
т.е. как бы не создается хэш массивов. :(
Название: сортировка хэша
Отправлено: NeoNox от 02 Июля 2004, 18:30:56
пришлось за тебя писать

%o = (
       001 => "one|two|three",
       002 => "four|five|six"
     );

$h{$_} = [split /\\|/, $o{$_}] foreach (keys %o);

foreach my $key (sort { $h{$a}[1] cmp $h{$b}[1] } keys %h){
    print "$key = $h{$key}[1] \\n";
}
Название: сортировка хэша
Отправлено: NeoNox от 02 Июля 2004, 18:32:36
Цитировать
AnnA:
# %h{"$ky"}=["$r", "$tt", "$m", "$d", "$h", "$rr", "$w"];

и шо это ты тут хотела сказать?
ошибки нужно исправлять а не комментировать.
$h{"$ky"}=["$r", "$tt", "$m", "$d", "$h", "$rr", "$w"];
Название: сортировка хэша
Отправлено: AnnA от 02 Июля 2004, 18:59:21
while (($ky,$ve) = each (%SH))
 {
   ($tt,$m,$d,$h,$rr,$w)=split (/\\|/,$ve);
   ($r,undef) = split(/\\|/,$R{$ky});
   $h{"$ky"}=["$r", "$tt", "$m", "$d", "$h", "$rr", "$w"];
 }

foreach my $key (sort { $h{$a}[1] <=> $h{$b}[1] } keys %h)
{ print "$key = $h{$key}[1]
"; }

УРА! :)
NeoNox :appl:
спасибо Вам огромное! :) Вы мне очень помогли! :chmok:
а теперь я буду перебирать вот эту единичку print "$key = $h{$key}[1] и спокойненько печатать нужные элементички. да, правильно? ой. сейчас попробую.
Название: сортировка хэша
Отправлено: NeoNox от 02 Июля 2004, 19:11:58
Да, правильно.
Название: сортировка хэша
Отправлено: vladsu от 03 Июля 2004, 03:51:27
Используя "The Schwartzian Transform"
A Fresh Look at Efficient Perl Sorting (http://www.sysarch.com/perl/sort_paper.html)

my %hash = (
            \'001\' => "a|f|z|h",
            \'002\' => "b|g|x|h",
            \'003\' => "c|e|z|f",
            \'004\' => "c|e|z|e",
);

my $pole_sortirovki = \'1\';        # Ukazi\'vaetsya ot 1 i do 4 dlya dannogo primera

print join "\\n",
      map  { $_->[0]." = ".$_->[1] } #Zdes perechislyayutsya polya kotorie nuzhno vivesti na pechat
      sort { $a->[$pole_sortirovki]  cmp  $b->[$pole_sortirovki] }
      map  { [$_ , split /\\|/, $hash{$_}] } keys %hash;

Первый "map" можно заменить, в зависимости от нужд, на

map  { $_->[0]." = ".$_->[1]."|".$_->[2]."|".$_->[3]."|".$_->[4] }

"sort" же можно заменить на

      sort { $a->[3]  cmp  $b->[3] ||
             $a->[4]  cmp  $b->[4] }

что даст возможность сортировать сначала по полю 3, можно изменить, а затем еще и по полю 4, что тоже можно изменить.
Название: сортировка хэша
Отправлено: AnnA от 03 Июля 2004, 16:15:25
vladsu здоровско! Пасиба! :)
для меня - самоучки, ой как трудно даются все эти примудрости. но интересненько. ;)
Название: сортировка хэша
Отправлено: commander от 03 Июля 2004, 16:45:18
Да простит меня модератор... не удержусь... :)
[moderator]
нет, не простит.
Название: сортировка хэша
Отправлено: vladsu от 05 Июля 2004, 11:22:59
Цитировать
AnnA:
для меня - самоучки...


Я пологаю, что 99%, если не 100, поситителей данного раздела форума такие же самоучки.