Forum Webscript.Ru
Программирование => Perl => Тема начата: commander от 08 Сентября 2004, 14:39:40
-
Задача следующая:
Имеем строку произвольной длинны с элементами вида "a:b" где а - индекс, b - индекс сортировки... :
"34:2,56:4,65:3,675:1,69:0"
Задача элементу ($id) изментить индекс сортировки на единицу в зависимоти от условия ($order=up или $order=down);
Моя спешная реализация:
---------------------------------------------------------------------------------#!/usr/bin/perl -w
use strict;
#исходные данные.
my $var="34:2,56:4,65:3,675:1,69:0";
my $id=56;
my $order="down";
#вызов функции order
$var=order($var, $id, $order);
print "$var\\n\\n";
#вывод и сортировка хеш массива
my @arr=split(",", $var);
my $Data;
for (my $NI=0; $NI<=$#arr; $NI++)
{
($Data->[$NI]{\'id\'}, $Data->[$NI]{\'order\'})=split(":", $arr[$NI]);
}
$Data=[ sort {$a->{order}<=>$b->{order}} @$Data ];
my $NI=0;
while ($Data->[$NI])
{
print "id=".$Data->[$NI]{\'id\'}."\\n";
$NI++
}
#конец вывода
sub order #функция сдвига сортировки
{
my ($var, $id, $order)=@_;
#определения максимального элемента
my @arr=split(",", $var);
my @arr_order;
my$i=0;
for my $el(@arr)
{
my ($id, $o)=split(":", $el);
$arr_order[$i]=$o;
$i++
}
@arr_order=sort {$b <=>$a} @arr_order;
my $max_elem=$arr_order[0];
###################################
#непосредственный сдвиг
my $var_1=$var;
$var=~/($id:)([0-9])/g;
my $ord=$2;
my $ord_old=$2;
if ($order eq "up")
{
if ($ord==0) #проверка на ноль
{
return $var;
exit;
}
else
{$ord--}
}
elsif ($order eq "down")
{
if ($ord==$max_elem) #проверка на максимальный элемент
{
return $var;
exit;
}
else
{$ord++}
}
$var_1=~/([0-9]+)(:$ord)/g;
my $id_2=$1;
$var=~s/($id:[0-9]+)/$id:$ord/g;
$var=~s/($id_2:[0-9]+)/$id_2:$ord_old/g;
return $var;
}
---------------------------------------------------------------------------------
есть идеи по уменьшению объема кода?
-
блин... ну вообщем смайлик это двоеточие ":" и скобка ")"
-
commander
Наворотил, млин...
По порядку:
#определения максимального элемента
my $max_elem = \'1\';
my @arr=split(/[\\,\\:]/, $var);
for (my $i = 1; $i <= @arr; $i+=2) {
$max_elem = $arr[$i] if $arr[$i] > $max_elem;
}
Хотя вообще проще сделать примерно так:
sub order
{
my ($var, $id, $order)=@_;
$var=~/$id\\:([0-9]+)/g;
my $ord = $1;
my $ord_new;
if ($order eq \'down\') {$ord_new = $ord - 1}
if ($order eq \'up\') {$ord_new = $ord + 1}
if ($var =~s /([0-9]+:)$ord_new/$1$ord/g) {$var =~s /$id\\:([0-9]+)/$id\\:$ord_new/g}
return $var
}
Может немного напутал с up - down, но принцип понятен...
P.S. Исправлено, забыл = в условии...
-
use strict;
use warnings;
use Data::Dumper;
my $var = \'34:2,56:4,65:3,675:1,69:0\';
my $id = 34;
#my $order = \'up\';
my $order = \'down\';
my %out = map {split \':\', $_} split ",", $var;
$order eq \'up\'
?
($out{sv($out{$id}+1)} = $out{$id} and $out{$id}++)
:
($out{sv($out{$id}-1)} = $out{$id} and $out{$id}--);
print Dumper(\\%out);
sub sv {
map {return $_ if $out{$_} eq $_[0]} keys %out;
}
to Admins Отключили бы "улыбки" в коде, или научите как это делать самому.
-
vladsu в полном ответе "Отключить иконки в Этом сообщении "
в быстрой форме - вставляйте между тегами...(прости Господи) РНР
-
vladsu
Вот только проверку крайних значений (max и min), что-то не вижу...
NeoNox
[OFF]А я, обычно, закрываю правый глаз, что бы видеть только букву P... ;)[/OFF]
-
Phoinix:
Вот только проверку крайних значений (max и min), что-то не вижу...
Не понял, о чём это Вы?
-
Phoinix
спасибо за помощь!
Отдельное спасибо vladsu!
vladsu
знаю тебя больше года... но никак не могу привыкнуть к твоему стилю написания кода... ;)
-
vladsu
commander
...
if ($ord==0) #проверка на ноль
...
if ($ord==$max_elem) #проверка на максимальный элемент
...
Я о том, что произойдет если минимальный элемент попытаются опустить вниз или максимальный вверх, у кого замещяется индекс сортировки?
при подстановке $id = 69; в массиве появляется 6-й элемент: 5=>0
-
при подстановке $id = 69; в массиве появляется 6-й элемент: 5=>0
Ааа, спасибо, об этом я в курсе, даже сразу предупредил commander\'а, он мне в асю писал прижде чем сюда запостить. И в условии ничего об этом не было сказано, т.е. я даже не знал, что в таких случаях делать, думаю он и сам сможет доделать.
-
vladsu
Уже доделал... спасибо! ;)