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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопросы по сложным структурам в Perl, хеши хешей, массивы хешей и т.п. 
:(
    Опции темы
Suppir
Дата 14.6.2010, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Добрый день!

У меня есть хеш хешей, который я составил следующим образом:

$hash_А{$document_ID}{Date}=$date;
$hash_А{$document_ID}{Code}=$code;
$hash_А{$document_ID}{Size}=$size;

Всего несколько тысяч уникальных $document_ID, и у каждого есть Date=>$date, Code=>$code, Size=>$size;


Потом я составил $hash_B, который выглядит аналогично (но документы имеют другие значения)

$hash_B{$document_ID}{Date}=$date;
$hash_B{$document_ID}{Code}=$code;
$hash_B{$document_ID}{Size}=$size;



Необходимо:

перебирая все $document_ID из $hash_A, 
найти аналогичный $document_ID в $hash_B;
если у этих документов $date, $code и $size  отличаются (хотя бы один из параметров),
но выдать ошибку для данного  $document_ID из $hash_A.





Это сообщение отредактировал(а) Suppir - 14.6.2010, 20:22
PM MAIL   Вверх
Suppir
Дата 14.6.2010, 20:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Забыл добавить:
$document_ID в $hash_А и  $document_ID в $hash_B
могут отличаться регистром символов (это численно-буквенная строка, вроде "abc-12").
Для каждого $document_ID из $hash_А нужно искать аналогичный $document_ID из  $hash_B без учета регистра. 
PM MAIL   Вверх
arto
Дата 14.6.2010, 20:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



перебирайте влоб:

while (my ($aa,$bb) = each %hasA) {
    while (my ($aaa,$bbb) = each %hashB) {
        ...
    }
}
PM MAIL ICQ   Вверх
vadiml
Дата 15.6.2010, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Если Вы можете привести к одному регистру, то быстрее брать document_ID из 1-го хеша
и для второго делать if ( exists $hash_B{$document_ID} ) { ... }
PM MAIL Jabber   Вверх
Suppir
Дата 15.6.2010, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



vadiml, document_ID и все остальные параметры нужно оставить как есть (регистр важен), но само сравнение нужно проводить без учета регистра.
Я воспользовался советом arto, только перебирал через foreach $key(keys %hash_A) {}

Это сообщение отредактировал(а) Suppir - 15.6.2010, 19:18
PM MAIL   Вверх
klem4
Дата 15.6.2010, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Как вариант:

Код

    my %a =
    (
        'abc'   => { date => 1, code => 1, size => 1  },
        'DEF'   => { date => 2, code => 2, size => 2  },
        'gHi'   => { date => 3, code => 3, size => 3  }
    );

    my %b =
    (
        'ABC'   => { date => 1, code => 1, size => 1  },
        'def'   => { date => 2, code => 2, size => 2  },
        'GhI'   => { date => 3, code => 0, size => 3  }
    );


    my $bad_key;

    for my $a_key ( keys %a )
    {
        last if defined $bad_key;

        for my $b_key ( keys %b )
        {
            last if defined $bad_key;

            if ( "\U$a_key" eq "\U$b_key" )
            {
                for ( qw[ date code size ] )
                {
                    unless ( $a{$a_key}->{$_} eq $b{$b_key}->{$_} )
                    {
                        $bad_key = $a_key; last;
                    }
                }
            }
        }
    }

    print defined $bad_key ? "bad key is $bad_key\n" : "ok\n";



PM MAIL   Вверх
Suppir
Дата 17.6.2010, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Подскажите, пожалуйста, как отсортировать хеш хешей?

Есть хеш хешей следующего вида:

$hash{$ID}{Type}
$hash{$ID}{Name}
$hash{$ID}{Date}
$hash{$ID}{Code}

Несколько тысяч ID. У каждого из них есть Type, Name, Date, Code. 

Необходимо сделать перебор хеша таким образом:

foreach $key(keys $hash){
      сделать что-то
}

При этом foreach должен выдавать нам элементы хеша в строгом порядке, учитывающим следующие приоритеты:
1. Type по алфавиту.
2. Date по убыванию даты (сначала самые свежие). Дата вида 8.04.2009 или 01.01.2010
3. Code по цифрам, чем больше цифра, тем больше приоритет
4. Name не учитываем.


Т.е. в первую очередь нужно выдать ID, у которого Type начинается с буквы "А", дата максимально поздняя, Code максимально большой.

Это сообщение отредактировал(а) Suppir - 17.6.2010, 12:34
PM MAIL   Вверх
ming
Дата 22.6.2010, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



думаю вам нужно смотреть в сторону связывания (tie)

http://search.cpan.org/~jgatcomb/Tie-Hash-...-0.10/Sorted.pm
PM MAIL ICQ Jabber   Вверх
KSURi
Дата 23.6.2010, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Хэши сортируются точно так же, как и все остальное.
Код

for my $key (
  sort { $hash{$b}{Code} <=> $hash{$a}{Code} }
  sort { Date_to_Days(split /\./, $hash{$b}{Date}) <=> Date_to_Days(split /\./, $hash{$a}{Date}) } # Date::Calc::Date_to_Days or whatever
  sort { $hash{$a}{Type} cmp $hash{$b}{Type} }
  keys %hash
)
{
  # $hash{$key} ...
}



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


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

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


 




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


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

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