Xpoint
   [напомнить пароль]

недопонимание с циклом foreach

Метки: [без меток]
[удл]
2006-10-01 17:59:27 [обр] пользователь удален

Что-то не могу сообразить где копать:
мне нужно во время перебора всего массива погрохать из него либо некоторые, либо все значения (далее неверный код):
foreach my $string(@catalog) { #
 if ($string ne "0") {
  my @strsplitted = split(/<>/,$string);
  print "$string <br>";
  splice @catalog, 0, 1;
 }
}
что-то в этом роде. Однако foreach сюда не подходит, судя по всему. Как бы так сделать, чтобы всегда обращаться к 0 элементу массива, но перебрать все?
Что-то в этом роде? :
$length=@catalog;
while ($length > 0) {
# тут обработка
--$length;
}

заранее спасибо.

спустя 1 минуту [обр] пользователь удален
splice - потому что не всегда удаляется первый элемент массива. Для простоты здесь 0 написал.
спустя 3 часа 20 минут [обр] Владимир Палант(387/4445)[досье]

Если удаляете только некоторые элементы массива:

for (my $i = 0; $i < @catalog; $i++) {

  # Делаем что-то

  splice(@catalog, $i--, 1);
}

Если точно удаляете все элементы массива:

while (@catalog) {
  my $string = shift @catalog;

  # Делаем что-то

}
спустя 15 часов [обр] Дворнов Роман(9/109)[досье]

Toxa (realbiker.ru)[досье]
а не проще

my @tmp = ();
foreach my $string (@catalog) { # 
  if ($string ne "0") {
    # ...
    push @tmp, $string;
  }
}
@catalog = @tmp;

С точки зрения асимптотики будет лучше, чем использовать splice.

спустя 4 дня [обр] Ваня Курманов[досье]

поскольку часто такая задачка возникает, я сделал себе раз и навсегда инструментик, который чистит все undefined элементы списка. И когда мне надо список менять, я делаю

foreach ( @list ) {
  if (...) { undef $_; }
}

а потом применяю инструментик к списку, в данном случае — к @list:

clear_undefined \@list;

А вот и инструментик:

sub clear_undefined ($) {
  my $ar = $_[0];
  my $cc = 0;
  my $i  = 0;
  while ( $i < scalar @$ar ) {
    my $v = $ar ->[$i];
    if ( not defined $v ) {
      splice @$ar, $i, 1;
      $cc ++;
      next;
    }
    $i ++;
  }
  return $cc;
}

Возвращает сколько почищено, т.е. удалено из списка.

спустя 11 часов [обр] Закиров Руслан(69/341)[досье]

Можно сделать вот так:

@array = grep defined, @array;

Или так:

sub clear_undefined ($) {
    my $a = shift;
    my $j = 0;
    for( my $i = 0; $i < @$a; $i++ ) {
        next unless defined $a->[$i];
        $a[$j++] = $a[$i];
    }
    my $cc = @$a - $j;
    splice @$a, $j;
    return $cc;
}

Если не нужно знать количество удаленных элементов, то можно еще упростить:

sub clear_undefined ($) {
    my $a = shift;
    my $j = 0;
    for( my $i = 0; $i < @$a; $i++ ) {
        next unless defined $a->[$i];
        $a[$j++] = $a[$i];
    }
    splice @$a, $j;
}
спустя 10 часов [обр] Дворнов Роман(9/109)[досье]
Закиров Руслан[досье] Мда, с grep самое нормальное решение. Собственно для того он и был придуман ;) (и почему сразу в голову не пришло)
@catalog = grep {
             if ($_ ne "0")
             { print $_; 0; }
             else
             { 1 }
           } @catalog;
Powered by POEM™ Engine Copyright © 2002-2005