Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> удалить элемент с массив хєша 
V
    Опции темы
gcc
Дата 19.3.2009, 04:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: 1
Всего: 17



не получается удалить или проверить не пуской ли массив-хэшей, то есть при проверке не пустой ли массив оно не адекватно как-то работает... if ($loop_data) {  или так if ($#{$loop_data}) { 

где может быть ошибка как удалить элемент массива и хэши в нем?

пример:

Код

    $sth->execute($args[0]);
    my $loop_data;
        push @{$loop_data}, $_ while $_ = $sth->fetchrow_hashref();
    $sth->finish();      
           
              foreach $_ (@{$loop_data}) {
            
            if ($_->{active_co} == 0 && ($_->{id_un} != $c->user->{user}->{id} 
                     || !$c->check_user_roles('moder_se') )            )  {           
            $_->{no_show_co} = 1;            
            }
            
            if ($_->{id_un} == $c->user->{user}->{id} 
                     || $c->check_user_roles('moder_se')             )  {           
            $_->{modering_co} = 1;            
            }
            
            if ($_->{hiden_co} == 1 && ($_->{id_un} != $c->user->{user}->{id} 
                     || !$c->check_user_roles('moder_se') )            )  {           
            $_->{no_show_co} = 1;
             
            }
                        
            if ($_->{hiden_g_co} == 1 && $c->user_exists() == 0  )  {           
            $_->{no_show_co} = 1;
  }
             $_->{close_se} = $_->{close_se} == 1 ? '1' : undef;    
             $_->{active_co} = $_->{active_co} == 0 ? '1' : undef;    
             
             $_->{edit_active_co} = $c->check_user_roles('moder_co') ? '1' : undef;                
             $_->{edit_close_co} = $c->check_user_roles('moder_co') ? '1' : undef;         
             
             # $_ = undef;
              # splice @{$loop_data}, $_, 10;
              
              # use Data::Dumper;   
              # print Dumper($_);           
           }
           
        for my $loopindex (0..$#{$loop_data}) 
       {

        for my $key (keys %{@{$loop_data}[$loopindex]})
              {
             #print "$key => @{$loop_data}[$loopindex]{$key},";
      
             }
       splice @{$loop_data}, $loopindex;
       }
                  use Data::Dumper;   
             print Dumper($loop_data);    
           
     #my $t = scalar @{$loop_data};
     #     print $t;
          
    if ($loop_data) { 
             $c->stash->{messages} = $loop_data;
    } else {
         $c->stash->{messages_error} = 1;
    }

PM WWW ICQ Skype GTalk Jabber   Вверх
pompei
Дата 19.3.2009, 05:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 7.9.2007

Репутация: 2
Всего: 6



а следующий код
Код

for my $loopindex (0..$#{$loop_data}) 
       {
        for my $key (keys %{@{$loop_data}[$loopindex]})
              {
             #print "$key => @{$loop_data}[$loopindex]{$key},";
      
             }
       splice @{$loop_data}, $loopindex;
       }
                  use Data::Dumper;   
             print Dumper($loop_data);    

вообще какаято лажа. Вы  когда делаете  splice @{$loop_data}, $loopindex; то $#{$loop_data} уменьшается на 1, $loopindex увеличивается на 1, т.е. в оконцове все четные элементы в массиве останутся а нечётные распечатуются и удалятся.

 if ($loop_data) { } - всегда будет истина, даже если тот массив, на который ссылается переменная, будет пустой.
правильно будет так
if (scalar(@{$loop_data}) == 0) {...} #т.е. "если количество элементов в массиве равно нулю"
здесь оператор scalar необязателен, но для спокойствия пусть стоит
ПРИМЕЧАНИЕ:  если массив используется в скалярном контексте, то возвращается количество элементов в мессиве

если вам просто надо очистить массив то следайте так
$loop_data = [];
а если на этот массив ещё кто-то ссылается и ихние ссылки тоже должны быть очищены, то вот так
@{$loop_data} = ();

Незабывайте что есть ещё такие функции
shift @{$loop_data} - удалить из массива первый элемент и вернуть его
pop @{$loop_data} - удалить из массива последний элемент и вернуть его


Это сообщение отредактировал(а) pompei - 19.3.2009, 05:45
--------------------
А всё оказывается гораздо проще: пассивные наноструктуры - активные наноструктуры - системы наносистем - молекулярные наносистемы - сингулярность! По пять лет на каждый этап.
PM MAIL   Вверх
gcc
Дата 19.3.2009, 08:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: 1
Всего: 17



как тогда правильно удалить конкретный элемент массива при переборе в завсисмости от условия? и проверить не пустой ли массив? (у меня массив с одним значением у котрого хеши, я удалил эти хэши, но а массив стал не пустой)

UPD: я поменял это @{$loop_data}, на это @loop_data без ссылки написал - вроде бы работает! 
если есть вариант более оптимальный, то скажите..


Это сообщение отредактировал(а) gcc - 19.3.2009, 08:47
PM WWW ICQ Skype GTalk Jabber   Вверх
pompei
Дата 19.3.2009, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 7.9.2007

Репутация: 2
Всего: 6



Код

use warnings;
use strict;



my $arr = [1,5,4,7,6,8,9,4,-8,5,6,7,8,-8,3,45,-8,-8,2,5,76,-8];
#my $arr = [-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8];

# Вот как можно из массива удалить все -8 (т.е. все элементы соответствующие некому условию)
my $index = 0;
while ( $index < scalar @$arr ) {
   my $element = $arr->[$index];
   if ($element == -8) {
       splice @$arr, $index;
       # $index увеличивать не нужно, т.к. он уже указывает 
       # на следующий, который встал на мето текущего
   } else {
       $index++;
       # ну а теперь нужно
   }
}

if (0 == scalar @$arr) {
    print "Ого все элементы в массиве удалили";
}



Это сообщение отредактировал(а) pompei - 19.3.2009, 13:45
--------------------
А всё оказывается гораздо проще: пассивные наноструктуры - активные наноструктуры - системы наносистем - молекулярные наносистемы - сингулярность! По пять лет на каждый этап.
PM MAIL   Вверх
amg
Дата 19.3.2009, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Цитата(gcc @  19.3.2009,  08:27 Найти цитируемый пост)
как тогда правильно удалить конкретный элемент массива при переборе в завсисмости от условия? 
Напрашивается воспользоваться grep:
Код
$arr = [ grep {$_ != -8} @$arr ];
Но это требует больше памяти и редактирование массива получается не "по месту". Зато понятно и коротко.

PM MAIL   Вверх
klem4
Дата 19.3.2009, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 27.7.2008

Репутация: 2
Всего: 2



Код

my @arr = (-8, 1, 2, 3, -8, 4, -8);
  for ( my $i = $#arr; $i + 1; ) {
    @arr = @arr[0..$i - 1, $i + 1..$#arr], next if $arr[$i] == -8;
    $i--;
  }

PM MAIL   Вверх
pompei
Дата 20.3.2009, 05:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 7.9.2007

Репутация: 2
Всего: 6



Цитата(gcc @  19.3.2009,  08:27 Найти цитируемый пост)
к
Код
$arr = [ grep {$_ != -8} @$arr ];
Но это требует больше памяти и редактирование массива получается не "по месту". Зато понятно и коротко.

Ну а если на этот массив ещё кто-то ссылается, то в таком случае у того останется старый массив

Кстати есть ещё вот такой синтаксис:
Код
$arr = [ grep $_ != -8, @$arr ];


Это сообщение отредактировал(а) pompei - 20.3.2009, 05:09
--------------------
А всё оказывается гораздо проще: пассивные наноструктуры - активные наноструктуры - системы наносистем - молекулярные наносистемы - сингулярность! По пять лет на каждый этап.
PM MAIL   Вверх
klem4
Дата 20.3.2009, 08:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 27.7.2008

Репутация: 2
Всего: 2



Потестировал немного, на массивах до 10000 при большом кол-ве удалений цикл быстрее грепа, а при больших чем 10000 масивах греп рвет.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0523 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.