Suckerupper с перечислением хэша
У меня есть код, который помог создать мой друг:
1 use LWP::Simple;
2 use HTML::TreeBuilder;
3 use Data::Dumper;
4
5 my $tree = url_to_tree( 'http://www.registrar.ucla.edu/schedule/schedulehome.aspx' );
6
7 my @selects = $tree->look_down( _tag => 'select' );
8 my @quarters = map { $_->attr( 'value' ) } $selects[0]->look_down( _tag => 'option' );
9 my @courses = map { my $s = $_->attr( 'value' ); $s =~ s/&/%26/g; $s =~ s/ /+/g; $s } $selects[1]->look_down( _tag => 'option' );
10
11 my $n = 0;
12
13 my %hash;
14
15 for my $quarter ( @quarters )
16 {
17 for my $course ( @courses )
18 {
19 my $tree_b = url_to_tree( "http://www.registrar.ucla.edu/schedule/crsredir.aspx?termsel=$quarter&subareasel=$course" );
20
21 my @options = map { my $s = $_->attr( 'value' ); $s =~ s/&/%26/g; $s =~ s/ /+/g; $s } $tree_b->look_down( _tag => 'option' );
22
23 for my $option ( @options )
24 {
25
26
27 print "trying: http://www.registrar.ucla.edu/schedule/detselect.aspx?termsel=$quarter&subareasel=$course&idxcrs=$option\n";
28
29 my $content = get( "http://www.registrar.ucla.edu/schedule/detselect.aspx?termsel=$quarter&subareasel=$course&idxcrs=$option" );
30
31 next if $content =~ m/No classes are scheduled for this subject area this quarter/;
32
33 $hash{"$course-$option"} = 1;
34 #my $tree_c = url_to_tree( "http://www.registrar.ucla.edu/schedule/detselect.aspx?termsel=$quarter&subareasel=$course&idxcrs=$option" );
35
36 #my $table = ($tree_c->look_down( _tag => 'table' ))[2]->as_HTML;
37
38 #print "$table\n\n\n\n\n\n\n\n\n\n";
39
40 $n++;
41 }
42 }
43 }
44
45 my $hash_count = keys %hash;
46 print "$n, $hash_count\n";
47
48 sub url_to_tree
49 {
50 my $url = shift;
51
52 my $content = get( $url );
53
54 my $tree = HTML::TreeBuilder->new_from_content( $content );
55
56 return $tree;
57 }
У меня проблемы с пониманием, какие строки 33
а также 45
делают. Я думаю, что по большей части я получаю то, что делает все остальное, а именно @selects
помещает все вещи, содержащиеся в двух выбранных тегах, в основной файл.aspx на рассматриваемом веб-сайте - я думаю, что размер @selects
2. Я также получаю, что с этого момента 0-й слот @selects
передается в @quarters
и аналогично слот position-1 передается в @courses. Каждый уникальный матч перечисляется и так n
общее количество курсов, предлагаемых в течение года. Теперь я не получаю то, что перечисляет $ hash_count. Я подозреваю, что это число уникальных предлагаемых курсов, так что где n
это животное, сродни (в псевдокоде)
sizeof( ['math1 FALL 2014' , 'math1 SPRING 2014'] ) = 2
Я подозреваю hash_count
это животное как
sizeof( ['math1 FALL 2014' , 'math1 SPRING 2014'] ) = 1
Правильно?
2 ответа
Цель хэша в этом случае - убедиться, что дубликаты удаляются из двух массивов, которые вы обрабатываете.
Это базовый принцип, хэш создается с вашими элементами "course" и "option". Когда появляется что-то новое, создается новая запись. Когда что-то уже существует, значение просто обновляется, как здесь:
$hash{"$course-$option"} = 1;
В конце концов keys
оператор получает все ключи созданного хэша. В этом (скалярном) контексте он просто возвращает количество ключей, отсюда и количество.
my $hash_count = keys %hash;
В основном код удаляет дубликаты.
Может быть предложено некоторое чтение хешей.
Но вот основы:
Скажем, мы уже определили хеш как это:
my %hash = ( one => 1, two => 2, three => 3 );
Мы можем присвоить новое значение хешу следующим образом:
$hash["four"] = 4;
И новое содержание будет:
( one => 1, two => 2, three => 3, four => 4 )
Но если использовать "ключ", который уже "существует", как это
$hash["two"] = 5;
Полученное содержимое будет таким
( one => 1, two => 5, three => 3, four => 4 )
Поэтому мы не добавляем дополнительную запись, его значение просто обновляется. Существует только одна запись для "два" и нет повторяющихся значений "два".
Мы можем, как и в последней части кода, получитьключи хеша, как показано ниже:
my @keys = keys %hash;
И это вернет список, который выглядит так:
( 'one', 'two', 'three', 'four' )
Они не будут в таком порядке, но только чтобы не усложнять. Но если мы не вернемся к тому, чтопримет список, как здесь:
my $count = keys %hash;
Затем возвращаетсяколичество элементов, содержащихся в хэше:
print "$count\n";
Будет выходной4
в результате.
Кодсобирает уникальные вхождения комбинированных значений "course" и "option", удостоверяется, что они уникальны, сохраняя его в качестве ключа в хэше. Затем, наконец, он возвращает количество ключей в вашей переменной $hash_count
, Затем печатает результат.
- Линия 33 магазина
$course-$option
в качестве ключа в хэше, с 1 в качестве связанного значения. Зачем? Хеши обеспечивают удобный и быстрый механизм поиска. Эти значения могли бы вместо этого быть сохранены в массиве, но последующие поиски (для проверки, был ли данный ключ виден ранее) не были бы такими быстрыми. - Строка 45 является синтаксически плотным оператором, но она по существу хранит количество ключей в хэше.
keys
Функция возвращает массив, содержащий - как вы уже догадались - все ключи в хэше. Тем не менее, поскольку переменная, которой он назначается ($hash_count
) является скаляром, массив оценивается в скалярном контексте. Массив, вычисляемый в скалярном контексте, - это просто количество записей в этом массиве.