Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Системное программирование > Структуры


Автор: OutlawZ 27.6.2011, 23:24
Приветствую, помогите решить небольшую проблему. 
Дана  структура:
Код

%struct = (
 OS => {
    Microsoft => ["Windows 3.11","Windows 95","Windows NT", "Windows XP", "Windows 7"],
    Linux      => ["Mandriva","Suse","Ubuntu","Kubuntu","DSL"],
    Apple      => ["Mac OS"],
 },
 MEMBERS => [
             { name => "Prosto Bill ",     company => "Microsoft", age => 45 },
             { name => "Linus Torvalds", company => "Linux",     age => 37 },
             { name => "James Morgan",   company => "LMUNION",   age => 22 },
            ],
);


Для поиска элементов которые не содержат не одного скаляра я понял что надо написать рекурсивную функцию, только одно но как ей передавать данные? Отдельно поиск я могу сделать но очень большой код может быть да и структуры разные могут быть.

Не понятно только одно как передавать параметры в функцию, просто может быть массив наполненный ссылками на три хеша как вот с этим работать? 
Буду признателен за ответ, просто намекните куда копать. 

Автор: afiskon 28.6.2011, 08:38
Ну берете хэш, перечисляете ключи, получаете ссылки на массивы, работаете с ними. В чем проблема то.

Автор: Pfailed 28.6.2011, 15:52
Нечто похожее
http://forum.vingrad.ru/forum/topic-328094.html

Автор: OutlawZ 28.6.2011, 16:34
ок, все разобрался.

Автор: OutlawZ 29.6.2011, 08:16
Извиняюсь что еще раз отвлекаю, как получать доступ к элементам структуры разобрался, но появились две проблемы 
Код

%struct = (
 OS => {
    Microsoft => ["Windows 3.11","Windows 95","Windows NT", "Windows XP", "Windows 7"],
    Linux      => ["Mandriva","Suse","Ubuntu","Kubuntu","DSL"],
    Apple      => ["Mac OS"],
       Members   => [
                  { name => "Bill Geths",     company => "Microsoft", age => 45 },
                  { name => "Linus Torvalds", company => "Linux",     age => 37 },
                  { name => " ",   company => unef,   age => 22 },
                 ],
 
 },
);


while (my ($key, $value) = each %struct) {
 find($value);
}

sub find {
 my ($value) = @_;
 my $ref = ref $value;
 
 if ( $ref eq 'HASH' ) {
    while ( ( $k, $v) = each %$value ) {
      find($v);
    }
 }elsif( $ref eq 'ARRAY' ) {
    for ( $i = 0; $i < @$value; $i++ ) {
     find($value->[$i]);
    } 
  }
}


Если перед вызовом рекурсий выводить значение то они выводятся без проблем, но используя пример выше приведенной ссылки где используется конструкция Data::Dumper пишет что вообще нечего не найдено 
Код

while (my ($key, $value) = each %struct) {
 if ( my $found = find($value) ) {
    print $found, ":\n", Dumper(eval "$found");
 }else{
    print "Not found\n";
 }
}

sub find {
 my ($value) = @_;
 my $ref = ref $value;
 
 if ( $ref eq 'HASH' ) {
    while ( ( $k, $v) = each %$value ) {
      if (my $hash = find($v) ) {
        return $hash;
      }
    }
 }elsif( $ref eq 'ARRAY' ) {
    for ( $i = 0; $i < @$value; $i++ ) {
      if ( my $array = find($value->[$i]) ) {
        return $array;
      }
    } 
  }
}

Выводит что нечего не найдено. Честно сказать я в тупике так как работал с структурами только два раза от силы. 
Удалял несколько элементов и искал пустые значение так и  тут проблемы, когда в структуре нет элемента он пишет что все в порядке. 
Помогите провести поиск ,найти пустые элементы и произвести удаление. уже 2 суток пытаюсь решить.

Автор: Pfailed 29.6.2011, 09:12
OutlawZ, у вас в функции нет проверки на пустоту. Или чего вы ей хотите сделать?

Автор: OutlawZ 29.6.2011, 15:58
Для проверки пустого значения я уже ставил но она не работает, скорее я где то ошибаюсь. но перепробовал все exitsts, defined , в т.е до вызова рекурсии была проверка есть ли значение в массиве или в ключе.

Я хочу просто проверить структуру на наличие пустых элементов,  и если таковые есть удалить. 

Автор: Pfailed 29.6.2011, 19:39
Что в вашем понимании пустое значение?

Автор: OutlawZ 29.6.2011, 20:00
в структуре то которое не содержит не одного скаляра

Автор: Pfailed 29.6.2011, 21:11
Получается пустой массив или хеш
Код

warn "empty array" unless @array;
warn "empty hash" unless %hash;


Автор: Pfailed 30.6.2011, 08:20
Один и вариантов такой, кажется работает верно

Код

use strict;
use Data::Dumper;

my %struct = (
    TEST1 => { root => '/home', dir => {} },
    TEST2 => [ "0001", [1, {}, 3], "0003", "russian" ],
    TEST3 => { },
    TEST4 => [ { a => [ [ { c => {}, d => {}, e => [] } ] ] } ],
);

clean(\%struct);
print Dumper \%struct;

sub clean {
    my $struct = shift;
    my $ref = ref $struct;
    
    if ($ref eq 'HASH') {
        foreach my $key (keys %$struct) {
            clean($struct->{$key});
            
            my $subref = ref $struct->{$key};
            if (($subref eq 'HASH' and !%{$struct->{$key}}) ||
                ($subref eq 'ARRAY' and !@{$struct->{$key}})) {
                delete $struct->{$key};
            }
        }
    }
    elsif ($ref eq 'ARRAY') {
        for (my $i=0; $i<@$struct; $i++) {
            clean($struct->[$i]);
            
            my $subref = ref $struct->[$i];
            if (($subref eq 'HASH' and !%{$struct->[$i]}) ||
                ($subref eq 'ARRAY' and !@{$struct->[$i]})) {
                splice @$struct, $i, 1;
                $i--;
            }
        }
    }
}


Цитата

$VAR1 = {
          'TEST1' => {
                       'root' => '/home'
                     },
          'TEST2' => [
                       '0001',
                       [
                         1,
                         3
                       ],
                       '0003',
                       'russian'
                     ]
        };


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)