Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > массив хешей


Автор: grebnev 30.6.2006, 15:26
Пожалуйста, покажите как динамически (в цикле) создать массив хешей.
Т.е. как я понял массив ссылок на хеши. 

Автор: Grig 30.6.2006, 16:56
Наверное так:

Код

#!/usr/bin/perl
%age = (
"Nat", 30,
"Pav", 40
);
%mon = (
"Jan",31,
"Feb",28
);
foreach $href(\%age, \%mon)
{
foreach $key(keys %$href)
    {
        print "$key=>$href->{$key}\n";
        }
}
 

Автор: grebnev 30.6.2006, 17:45
ну а как же ссылки
я тут читаю, говорят нельзя создавать хеши хешей
нужно использовать что-то вроде массива указателей
в общем поэтому и возник вопрос 

Автор: grebnev 30.6.2006, 22:21
Ну в общем суть дела в следующем:
работаю с БД (использую DBI)
методом $res1->fetchrow_hashref получаю из БД строку
хочу сначала данные сохранить в хеш
а после вывести в виде 
Строка(ИмяПоля->Значение, ИмяПоля->Значение, ИмяПоля->Значение)
Строка(ИмяПоля->Значение, ИмяПоля->Значение, ИмяПоля->Значение)
Строка(ИмяПоля->Значение, ИмяПоля->Значение, ИмяПоля->Значение)
Уже использовал и хеш массивов и массив хешей и даже на определенном этапе получил результат
но код изменил и теперь опять ни хр-на не работает smile. 

Автор: grebnev 1.7.2006, 00:01
ну че ни кто ни чего не расскажет
вернее покажет

заранее сенкс 

Автор: rcdimon 1.7.2006, 09:44
Код

    my $sql = 'SQL Request';
    my @row;
    my $sth = $dbh->prepare($sql);
    $sth->execute;
    if  (($sql =~ m/^select/i) || ($sql =~ m/^show/i)){
        while (my $ref = $sth->fetchrow_hashref()) {
                  push @row, $ref;
             }
           $sth->finish ();
    }



Теперь у тебя есть массив хешей @row

Точнее массив ссылок на хеши.. smile   

Автор: vumnik 1.7.2006, 16:05
А у меня вот такой примерчик. Простовато, зато всё понятно.
Код

@a =("a","b","c","d");
@b = (1,2,3,4,5,6,7);

foreach $i (@a) {
    foreach $j (@b) {
        $mas{$i}{$j} = "$i$j";
    }
}

foreach $i (sort keys %mas) {
    print $i,"\n";
    foreach $j (sort keys %{$mas{$i}}) {
        print "\t", $j, "  ", $mas{$i}{$j}, "\n";
    }
}

$ff = <>;
 

Автор: alyam 2.8.2006, 13:35
помогите написать программку. зачет горит )
файл :
user1 group1 sdvsdhgfsgf
user3 group7 sdjkhksdjgfskgf
user2 group3 sdjhsdjks
user3 group1

нужно отсортировать в убывающем порядке и вывести в файл user - и все группы group, в которых user встречается:
user3 group1,group7
user2 group3
user1 group1

Автор: Nab 2.8.2006, 14:23
Код

#!/usr/bin/perl

use strict;

my $file1 = "users.txt";
my $file2 = "sort_users.txt";

open (FILE, "<$file1") || die "Cannot open file $file1: $!\n";

my %user;
while (<FILE>) {
    /^(\w+)\s+(\w+).*/;
    push ( @{$user{$1}}, $2);
}

close FILE;

open (FILE, ">$file2") || die "Cannot open file $file2: $!\n";
foreach (reverse sort keys %user) {
    print FILE $_." ".join(', ', @{$user{$_}})."\n"
}

close FILE;

1;


Добавлено @ 14:26 
ага, можно еще вот так:
Код

    print FILE $_." ".join(', ', sort @{$user{$_}})."\n"


тогда и группы будут отсортированы по взрастанию...

Автор: Danissimo 14.8.2006, 16:42
а вот такое подойдет:

Код

use constant N => 10;

my @arrayOfHashRefs;
for (my $i = 0; $i < N; $i++) {
    my $refToHash = {};
    push(@arrayOfHashRefs, $refToHash);
}


а вот про зачет:

Код

# Скажем, дескриптор входногофайла -- F
my %users;
foreach my $line (<F>) {
    my($name, $group) = split(' ', $line);
    my $groups = $users{$name};
    if (!$groups) {
        $users{$name} = ($groups = []);
    }
    push(@$groups, $group);
}

foreach my $user (sort {$b cmp $a} keys(%users)) {
    print("$user ");
    my $arrRef = $users{$user};
    my $comma = "";
    foreach (@$arrRef) {
        print("$comma$_");
        $comma = ",";
    }
    print("\n");
}


Автор: Nab 15.8.2006, 23:00
Danissimo, извини но не надо так писать... Если учиться то сразу правильно....

Я перепишу твой код повнятней... И постараюсь описать почему...

Код

# Эта высокоуровневая конструкция настолько редко используется, что ты даже не представляешь, 
# и начинающим она нафиг не нужна...
#use constant N => 10;
# меняем на
my $N = 10;

my @arrayOfHashRefs;
#Вот так будет проще...
# без лишних присваиваний
foreach (1..$N) {
    push(@arrayOfHashRefs, {});
}


Ну или вот эта интересная конструкция :
Код

@arrayOfHashRefs = {} x $N;

дает тот же результат...

А теперь вот этот код:
Код

# Скажем, дескриптор входногофайла -- F
my %users;
foreach my $line (<F>) {
    my($name, $group) = split(' ', $line);

# Скажем для начинающих стоило бы описать откуда он взялся....
# Ну да ладно, примем как данность..
# Упрощаем, избавляясь от лишних переменных 
while (<F>) {
# здесь подразумевается что делим переменную $_,
# а разделителем если он не определен по умолчанию выступает любой пробельный символ...
# там может стоять табуляция а не пробел...
    my($name, $group) = split;


# вот дальше идет нездоровая хотя и рабочая конструкция
    my $groups = $users{$name};
    if (!$groups) {
        $users{$name} = ($groups = []);
    }
    push(@$groups, $group);

# Заменим ее на вот такую:
    push(@{$users{$name}}, $group);
# Возможно она не понятна новичку, но она абсолютно адекватна предыдущей.
# Мы представляем значение хеша $users{$name} как ссылку на массив и тут же добавляем к нему группу
# проверка на существование как по мне, бессмысленная трата ресурсов.
}

А вот этот код:
Код

# вот блин, не надо так делать,  нужно по максимуму использовать средства языка
# и его дефолтную переменную $_
# сортировка и так идет строковая
# кстати в задании речь шла об обратном порядке
foreach my $user (sort {$b cmp $a} keys(%users)) {
   print("$user ");
    my $arrRef = $users{$user};
    my $comma = "";
# про split знаем а про join нет.... Интересно учимся... или лекцию про join прогулял?
    foreach (@$arrRef) {
        print("$comma$_");
        $comma = ",";
    }
    print("\n");
}

меняем на:
Код

foreach (reverse sort keys(%users)) {
   # выводим юзера из переменной $_
    print;
    # пробел после него
    print " "; 
    # здесь таже конструкция со ссылкой...
    print join(',', @{$users{$_}});
    # а туточки перевод строки
    print("\n");
}

# это не очень здоровая конструкция, просто нафиг использовать 4 print 
# если можно как в моем предыдущем сообщении


Возможно использование ссылок для начинающего и непонятно, хотя вроде старался разжевать, 
но на тему топика тоже стоит глянуть.
Здесь правда наоборот, хеш ссылок на массивы smile

Автор: Danissimo 16.8.2006, 13:38
Цитата(Nab @ 15.8.2006,  23:00)

# Эта высокоуровневая конструкция настолько редко используется, что ты даже не представляешь
#use constant N => 10;

Почему? Я так расуждаю, если значение переменной я могу поменять, и компилятор мне ничего про это не скажет, то с константой так не пройдет. Это верно? Если да, то почему не надо использовать constant. Я не согласен, что "редко используется" -- это аргумент.

Цитата(Nab @ 15.8.2006,  23:00)

Код

foreach (1..$N) {
    push(@arrayOfHashRefs, {});
}


Зачот!

Цитата(Nab @ 15.8.2006,  23:00)

Код

@arrayOfHashRefs = {} x $N;


Двойной ЗАЧОТ!

Цитата(Nab @ 15.8.2006,  23:00)

Код

# вот дальше идет нездоровая хотя и рабочая конструкция
    my $groups = $users{$name};
    if (!$groups) {
        $users{$name} = ($groups = []);
    }
    push(@$groups, $group);

# Заменим ее на вот такую:
    push(@{$users{$name}, $group);


Хе, получается, такая штука. Предположим, что элемента $users{$name} еще не существует. И получается, что @{$users}{$name} преобразует несуществующий элемент к массиву. Тихо шифером шурша, крыша едет неспеша...

Цитата(Nab @ 15.8.2006,  23:00)

Код

foreach (1..$N) ...

# Упрощаем, избавляясь от лишних переменных 
while (<F>) { ...

# [...] нужно по максимуму использовать средства языка
# и его дефолтную переменную $_


Почему "нужно"?

Цитата(Nab @ 15.8.2006,  23:00)

Код

# сортировка и так идет строковая
# кстати в задании речь шла об обратном порядке
foreach my $user (sort {$b cmp $a} keys(%users)) {
# про split знаем а про join нет.... Интересно учимся... или лекцию про join прогулял?


"сортировка и так идет строковая" -- это к чему?
"кстати в задании речь шла об обратном порядке" -- а у меня как?
"# [...] или лекцию про join прогулял?" -- пожалуй, что так тоже можно сказать =)

Цитата(Nab @ 15.8.2006,  23:00)

Возможно использование ссылок для начинающего и непонятно, хотя вроде старался разжевать, 
но на тему топика тоже стоит глянуть.
Здесь правда наоборот, хеш ссылок на массивы smile

Это я не понял к чему.

Вобщем, я в шоке от такого афигительного качества ответа. Пиши еще =)

Автор: Nab 16.8.2006, 14:09
Цитата(Danissimo @ 16.8.2006,  13:38)
Цитата(Nab @ 15.8.2006,  23:00)

# Эта высокоуровневая конструкция настолько редко используется, что ты даже не представляешь
#use constant N => 10;

Почему? Я так расуждаю, если значение переменной я могу поменять, и компилятор мне ничего про это не скажет, то с константой так не пройдет. Это верно? Если да, то почему не надо использовать constant. Я не согласен, что "редко используется" -- это аргумент.

Давай пока сделаем так, покажи мне в условии задачи, где речь шла о константе?
По условию скорее всего там будет именно переменная а не константа.
А подключение лишних модулей влияет на производительность.

Цитата

Цитата(Nab @ 15.8.2006,  23:00)

Код

# вот дальше идет нездоровая хотя и рабочая конструкция
    my $groups = $users{$name};
    if (!$groups) {
        $users{$name} = ($groups = []);
    }
    push(@$groups, $group);

# Заменим ее на вот такую:
    push(@{$users{$name}, $group);


Хе, получается, такая штука. Предположим, что элемента $users{$name} еще не существует. И получается, что @{$users}{$name} преобразует несуществующий элемент к массиву. Тихо шифером шурша, крыша едет неспеша...

Я тебе сочуствую по этому поводу...  smile 
Perl очень дружественнен в этом смысле, а твоя конструкция "@{$users}{$name}" вообще безсмысленна.
Я сделал опечатку (исправил кстати), но я даже не подозревал, что ты до такого додумаешься smile читай книжки...
А уж если хочется сделать проверку то вот такая конструкция самое то ...
Код

$users{$name} ||= [];


Цитата

Цитата(Nab @ 15.8.2006,  23:00)

Код

foreach (1..$N) ...

# Упрощаем, избавляясь от лишних переменных 
while (<F>) { ...

# [...] нужно по максимуму использовать средства языка
# и его дефолтную переменную $_


Почему "нужно"?

Потому что так проще код читать... он меньше места занимает и компилируется быстрее
Цитата

Цитата(Nab @ 15.8.2006,  23:00)

Код

# сортировка и так идет строковая
# кстати в задании речь шла об обратном порядке
foreach my $user (sort {$b cmp $a} keys(%users)) {
# про split знаем а про join нет.... Интересно учимся... или лекцию про join прогулял?


"сортировка и так идет строковая" -- это к чему?

К тому что  "{$b cmp $a}" нафиг не нужно
Цитата

"кстати в задании речь шла об обратном порядке" -- а у меня как?

К тому что используешь нееффективный способ сортировки, есть простая функция reverse  smile 
Цитата

"# [...] или лекцию про join прогулял?" -- пожалуй, что так тоже можно сказать =)

Цитата(Nab @ 15.8.2006,  23:00)

Возможно использование ссылок для начинающего и непонятно, хотя вроде старался разжевать, 
но на тему топика тоже стоит глянуть.
Здесь правда наоборот, хеш ссылок на массивы smile

Это я не понял к чему.

Что именно здесь не понятно?
Цитата

Вобщем, я в шоке от такого афигительного качества ответа. Пиши еще =)


Большая просьба использовать нормальный русский язык... а с таким общением на udaff.com...

Автор: Danissimo 16.8.2006, 15:11
В условии про константу речи не было. Однако, ты ж рекомендуешь их вообще не использовать. Вот я и спрашиваю, почему же? Говоришь, на производительность влияет. Ок, возможно. Чем докажешь?

Наплевать на опечатку. И книжки читаю. Ты как считаешь, если б не было вопросов, спрашивал бы? Ты можешь сказать, где в документации описано, как перл "пошагово выполняет" такую конструкцию:
push(@{$users{$name}}, 'x');
Хочется не проверку сделать, а понять, как перл "думает". Документация пока света не пролила. Может ты сможешь показать место в доке, из которого ясно следует, как перл в этой ситуации думает?

"Потому что так проще код читать... он меньше места занимает и компилируется быстрее" -- и это все?

"К тому что используешь нееффективный способ сортировки, есть простая функция reverse" -- аа, то есть сортируется все-таки правильно. А за reverse спасибо.

Да, чет я не вижу среди моих вопросов вопроса о том, где и какой язык мне использовать.

Пиши еще =)

Автор: Nab 16.8.2006, 15:31
Цитата(Danissimo @ 16.8.2006,  15:11)
В условии про константу речи не было. Однако, ты ж рекомендуешь их вообще не использовать. Вот я и спрашиваю, почему же? Говоришь, на производительность влияет. Ок, возможно. Чем докажешь?

Доказывать ничего не собираюсь, это очевидно... 
Или что такое use, не знаешь?
Цитата

Наплевать на опечатку. И книжки читаю. Ты как считаешь, если б не было вопросов, спрашивал бы? Ты можешь сказать, где в документации описано, как перл "пошагово выполняет" такую конструкцию:
push(@{$users{$name}}, 'x');
Хочется не проверку сделать, а понять, как перл "думает". Документация пока света не пролила. Может ты сможешь показать место в доке, из которого ясно следует, как перл в этой ситуации думает?

perldoc perlreftut
perldoc perldsc
perldoc  perllol

Проверка разных конструкций как раз и позволит понять как раскрываются скобки и происходит приведение типов...
Я не вижу смысла пересказывать своими словами документацию...

Цитата

"Потому что так проще код читать... он меньше места занимает и компилируется быстрее" -- и это все?

А этого мало? Ты же не спрашивал, а давал ответ....
Цитата

Да, чет я не вижу среди моих вопросов вопроса о том, где и какой язык мне использовать.

Пиши еще =)

В таком случае не вижу смысла в нашем общении вообще... 
Как правило безграмотный человек такой же код пишет, с одной стороны, а с другой, мне просто не приятно это читать smile Так что уж извини, но тебе очень не хватает теоретической подготовки... Читай книжки, на форуме врядли кто будет тратить на это время smile

Автор: Danissimo 16.8.2006, 17:18
Ладно, можешь не продолжать. Все равно, чувствую, ничего более ценного не скажешь.

Спасибо и на том, что сказал =)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)