Титульная страница
ISO 9000 ISO 14000 Forum
Титульная страница
Цель системы качества
Управление качеством
ISO
ISO 9000
ISO 13485
ISO 14000
ISO 17025
OHSAS 18001
ISO 19011
Total Quality Management
Project Management
Фармацевтика
Отраслевые стандарты
Информационные технологии
Оформление документации
Ссылки 
Поиск на сайте
Forum
Реклама на сайте





Доступ к элементам массива осуществляется например таким образом(выводится случаный элемент массива):
print $mass[ramd $#mass];

В переменной $#mass содержится размер массива-1, т.к. нуумерация элемента массива начинается с нулевого элемента.

Примеры использования

Постраничный вывод новостей с разбиением по датам

Предположим есть файл news.dat со строками(не суть что разделитель, разделитель определяется переменной $/, которую можно в начале кода переопределить) вида:


20010717<A href="http://www.netoscope.ru/news/" target=_new>news1</a>&nbsp;&nbsp;&nbsp;&nbsp;[Нетоскоп]
20010717<A href="http://www.utro.ru/news/" target=_new>news2</a>&nbsp;&nbsp;&nbsp;&nbsp;[Утро]
20010718<A href="http://www.compulenta.ru/" target=_new>news3</a>&nbsp;&nbsp;&nbsp;&nbsp;[Компьюлента]
20010718<A href="http://www.compulenta.ru" target=_new>news4</a>&nbsp;&nbsp;&nbsp;&nbsp;[Компьюлента]
20010718<A href="http://www.kommersant.ru/news/" target=_new>news5</a>&nbsp;&nbsp;&nbsp;&nbsp;[КоммерсантЪ]
20010719<A href="http://www.echo.msk.ru/7news/" target=_new>news6</a>&nbsp;&nbsp;&nbsp;&nbsp;[Эхо Москвы]
20010719<A href="http://www.echo.msk.ru/7news/" target=_new>news7</a>&nbsp;&nbsp;&nbsp;&nbsp;[Эхо Москвы]

где даты поставлены задом наперед, сначала год, затем месяц, затем день, так сравнивать легче, ибо год максимален, месяц тоже максимален, и деть тоже максимален. Иначе для сортировки по дате пришлось бы вводить двенадцатиричную систему счисления для месяцев и затем 60-тиричную систему счисления для часов, минут и секунд.

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


#!/usr/bin/perl -wT
print "content-type: text/html\n\n";
use CGI 'param';
 $pos = param('pos');
 $n = 5;
 $k = 5;
 $url = "q.pl";
open F, "<news.dat"; @mass=<F>; close F;

@m1=grep{!$_{$_}++}
 map{/^(\d\d\d\d\d\d\d\d)/} @mass;

foreach $u(0 .. $#m1){
 foreach $n(@mass){
 chomp $m1[$u];
 push @{$ha{$m1[$u]}}, $n if($n=~m/^$m1[$u]/)
 }
}
print "<a name=top>";
for $k(reverse sort keys %ha){
 $k=~s|^(\d\d\d\d)(\d\d)(\d\d)|$3\.$2\.$1|;
 push(@re, " <a href=\"#$k\">$k</a> ");
}
print "<center>";
&res(@re); 
print "</center>";
for $k(reverse sort keys %ha){
 $m=$k; $m=~s|^(\d\d\d\d)(\d\d)(\d\d)|$3\.$2\.$1|;
 $tr="<b><a name=\"$m\">$m</b> <a href=\"#top\">top</a><ul>";
 foreach $im(@{$ha{$k}}){ $im=~s!$k|<br>!!; $tr.="<li>$im";}
 $tr.="</ul>";
 push @res, "$tr\n";
}
push @res, "";
&res(@res);
sub res{
 local @res=@_;
 if($#res>$n-1){
 print "<p><center><font size=-1><b>";
 foreach($j=0; $j<=$#res; $j++){
 push(@pervij,"$j") if($j<=$pos && $j % $n == 0);
 push(@vtoroj,"$j") if($j>=$pos+$n && $j % $n == 0);
 }
 foreach $elem(@pervij){
 if($elem/$n>=$pervij[$#pervij]/$n-$k && $res[$#res] ne '<!--end-->'){
 if($elem==$pervij[$#pervij] && $res[$#res] ne '<!--end-->')
	 {push(@nach ,($elem/$n+1));}
 else{ push(@nach, " <a href=\"$url?pos=$elem\">".($elem/$n+1)."<\/a> |\n");}
 }
 if($#pervij > $k && $res[$#res] ne '<!--end-->'){
 push(@back, "<a href=\"$url?pos=".($pos-$n)."\"><<<\/a>")
 }
 } 
 print $back[$#back];
 print @nach;
 foreach $elem1(@vtoroj){
 if ($elem1/$n<=$pos/$n+$k && $res[$#res] ne '<!--end-->'){
 print " | <a href=\"$url?pos=$elem1\">".($elem1/$n+1)."<\/a> \n";
 }
 if($#vtoroj > $k-1 && $res[$#res] ne '<!--end-->'){
 push(@back1, "<a href=\"$url?pos=".($elem1)."\">>><\/a>")
 }
 } 
 print "$back1[0]</b></font></center>";
 }
 $#pervij=-1; $#vtoroj=-1; $#back=-1; $#nach=-1; $#back1=-1;
 print "<p>";
 for ($i=$pos; $i<$pos+$n; $i++) { print $res[$i]}
}
Разберем работу программы:


@m1=grep{!$_{$_}++}
 map{/^(\d\d\d\d\d\d\d\d)/} @mass;

составляем массив цифр, т.е. массив дат, map{/^(\d\d\d\d\d\d\d\d)/} @mass составляет список цифр, указанных в регулярном выражении. Следующая строчка grep{!$_{$_}++} - убирает одинаковые даты, т.к. в списке новостей может быть несколько новостей за один день. Получаем массив @m1 с днями, которые были с новостями.


foreach $u(0 .. $#m1){
 foreach $n(@mass){
 chomp $m1[$u];
 push @{$ha{$m1[$u]}}, $n if($n=~m/^$m1[$u]/)
 }
}

создаем хеш массивов @{$ha{$m1[$u]}}, в которых определенному дню будет соответствовать несколько новостей.


for $k(reverse sort keys %ha){
 $k=~s|^(\d\d\d\d)(\d\d)(\d\d)|$3\.$2\.$1|;
 push(@re, " <a href=\"#$k\">$k</a> ");
}
print "<center>";
&res(@re); 
print "</center>";

выводим линейку дат, если при выводе 5 дней(значение числа дней содержится в переменной $n = 5;) число новостей таково, что будет помещаться на более чем одной странички, вобщем для быстрой навигации.


for $k(reverse sort keys %ha){
 $m=$k; $m=~s|^(\d\d\d\d)(\d\d)(\d\d)|$3\.$2\.$1|;
 $tr="<b><a name=\"$m\">$m</b> <a href=\"#top\">top</a><ul>";
 foreach $im(@{$ha{$k}}){ $im=~s!$k|<br>!!; $tr.="<li>$im";}
 $tr.="</ul>";
 push @res, "$tr\n";
}
push @res, "";
&res(@res);

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


sub res{
 local @res=@_;
 if($#res>$n-1){
 print "<p><center><font size=-1><b>";
 foreach($j=0; $j<=$#res; $j++){
 push(@pervij,"$j") if($j<=$pos && $j % $n == 0);
 push(@vtoroj,"$j") if($j>=$pos+$n && $j % $n == 0);
 }
 foreach $elem(@pervij){
 if($elem/$n>=$pervij[$#pervij]/$n-$k && $res[$#res] ne '<!--end-->'){
 if($elem==$pervij[$#pervij] && $res[$#res] ne '<!--end-->')
	 {push(@nach ,($elem/$n+1));}
 else{ push(@nach, " <a href=\"$url?pos=$elem\">".($elem/$n+1)."<\/a> |\n");}
 }
 if($#pervij > $k && $res[$#res] ne '<!--end-->'){
 push(@back, "<a href=\"$url?pos=".($pos-$n)."\"><<<\/a>")
 }
 } 
 print $back[$#back];
 print @nach;
 foreach $elem1(@vtoroj){
 if ($elem1/$n<=$pos/$n+$k && $res[$#res] ne '<!--end-->'){
 print " | <a href=\"$url?pos=$elem1\">".($elem1/$n+1)."<\/a> \n";
 }
 if($#vtoroj > $k-1 && $res[$#res] ne '<!--end-->'){
 push(@back1, "<a href=\"$url?pos=".($elem1)."\">>><\/a>")
 }
 } 
 print "$back1[0]</b></font></center>";
 }
 $#pervij=-1; $#vtoroj=-1; $#back=-1; $#nach=-1; $#back1=-1;
 print "<p>";
 for ($i=$pos; $i<$pos+$n; $i++) { print $res[$i]}
}

локализуем массив @res: local @res=@_; - получили массив, переданный попрограмме. Далее if($#res>$n-1){blah blah blah} если число элементов массива больше, чем 5, то показываем строчку прокрутки.

Разбиваем массив @res на массивы до текущей страницы(@pervij) и после текущей страницы(@vtoroj):


 foreach($j=0; $j<=$#res; $j++){
 push(@pervij,"$j") if($j<=$pos && $j % $n == 0);
 push(@vtoroj,"$j") if($j>=$pos+$n && $j % $n == 0);
 }

размерность массивов @pervij и @vtoroj кратна(кратность определяется оператором %) числу $n, т.е. это массивы до текущей страницы и после текущей страницы, в броузере, если пользователь находится допустим на 10 странице результатов до текущей все то, что до цифры без ссылки, после текужей это все то, что после цифры без ссылки, включая линейки прокрутки << и >>: << 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 >>

Эти массивы содержат число пятерок(для $n=5;) элементов массива @res.


 foreach $elem(@pervij){
 if($elem/$n>=$pervij[$#pervij]/$n-$k && $res[$#res] ne '<!--end-->'){
 if($elem==$pervij[$#pervij] && $res[$#res] ne '<!--end-->')
	 {push(@nach ,($elem/$n+1));}
 else{ push(@nach, " <a href=\"$url?pos=$elem\">".($elem/$n+1)."<\/a> |\n");}
 }
 if($#pervij > $k && $res[$#res] ne '<!--end-->'){
 push(@back, "<a href=\"$url?pos=".($pos-$n)."\"><<<\/a>")
 }
 } 
Цикл для показа элементов предыдущих страниц << 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

т.е. если $elem/$n>=$pervij[$#pervij]/$n-$k, то это значит, что выбираются страницы элементов до текущей позиции, включая е?, т.е. 2, 3, 4, 5 и 6 - цифра 7 это текущая позиция, которая определяется условием if($elem==$pervij[$#pervij] && $res[$#res] ne '<!--end-->'). Зачем тут стоит <!--end--> будет видно позднее в разборе админской части этой ленты новостей.

Условие


 if($#pervij > $k && $res[$#res] ne '<!--end-->'){
 push(@back, "<a href=\"$url?pos=".($pos-$n)."\"><<<\/a>")
 }

значит что если существуют элементы массива @pervij больше, чем $k=5, то для таких елементов нужно ставить знички прокрутки << и >>. Для массива @vtoroj условия определяются аналогичным образом, учитывая, что элементы для него должны быть больше определенного числа $pos, которое определяет текущее значение показываемой пятерки дат. Вывод самих новостей осуществляется циклом


 for ($i=$pos; $i<$pos+$n; $i++) { print $res[$i]}

который берет элементы массива $res[$i] до элемента $n, т.е. допустим пользователь находится на странице 10, значит должен производится вывод новостей с 50 по 55-ю включительно.

Вывод результатов помещен в подпрограмму, т.е. существует некая переносимость кода из одного скрипта в другой. В скрипте подпрограмма используется дважды, когда нужно вывести число дат по $n штук и когда нужно вывести сами новости в количестве $n штук на страничку.

Rambler's Top100
Hosted by uCoz