The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Хэш массивов, !*! Cyrus_user, 05-Апр-07, 06:58  [смотреть все]
Привет,
есть несколько хэшей, некоторые ключи у них совпадают. хочу объединить хэши, чтобы ключи остались уникальными, а все значения стали массивами.
Или я не туда пошёл... вообщем у меня такие входные данные
я получаю разномастную статистику в таком виде $hash{$ident}="some1"
из кучи сборщиков статистики получаю пачку хэшей, где в большинстве ключи $ident совпадают, но есть и встречающиеся по 1-му разу.
в глобальный сборщик пытаюсь передать примерно такое:
$hash{$ident_total}=@array, где @array=(hash1{$ident},hash2{$ident}) и если значения отсутствуют, то просто ноль.
но что-то ничего в голову не лезет, подсказку не дадите? застрял на этапе формирования массива из значений всех уникальных ключей хэшей.
  • Хэш массивов, !*! A, 09:55 , 05-Апр-07 (1)
    >Привет,
    >есть несколько хэшей, некоторые ключи у них совпадают. хочу объединить хэши, чтобы
    >ключи остались уникальными, а все значения стали массивами.
    >Или я не туда пошёл... вообщем у меня такие входные данные
    >я получаю разномастную статистику в таком виде $hash{$ident}="some1"
    >из кучи сборщиков статистики получаю пачку хэшей, где в большинстве ключи $ident
    >совпадают, но есть и встречающиеся по 1-му разу.
    >в глобальный сборщик пытаюсь передать примерно такое:
    >$hash{$ident_total}=@array, где @array=(hash1{$ident},hash2{$ident}) и если значения отсутствуют, то просто ноль.
    >но что-то ничего в голову не лезет, подсказку не дадите? застрял на
    >этапе формирования массива из значений всех уникальных ключей хэшей.

    # данные
    %h1=qw/a 1 b 2/;
    %h2=qw/a 3 c 4/;
    # решение
    %h=();
    foreach (\%h1, \%h2) {
      while (($a, $b)=each(%$_)) {
        push @{$h{$a}}, $b
      }
    }

    • Хэш массивов, !*! Cyrus_user, 08:32 , 06-Апр-07 (3)
      >>Привет,
      >>есть несколько хэшей, некоторые ключи у них совпадают. хочу объединить хэши, чтобы
      >>ключи остались уникальными, а все значения стали массивами.
      >>Или я не туда пошёл... вообщем у меня такие входные данные
      >>я получаю разномастную статистику в таком виде $hash{$ident}="some1"
      >>из кучи сборщиков статистики получаю пачку хэшей, где в большинстве ключи $ident
      >>совпадают, но есть и встречающиеся по 1-му разу.
      >>в глобальный сборщик пытаюсь передать примерно такое:
      >>$hash{$ident_total}=@array, где @array=(hash1{$ident},hash2{$ident}) и если значения отсутствуют, то просто ноль.
      >>но что-то ничего в голову не лезет, подсказку не дадите? застрял на
      >>этапе формирования массива из значений всех уникальных ключей хэшей.
      >
      ># данные
      >%h1=qw/a 1 b 2/;
      >%h2=qw/a 3 c 4/;
      ># решение
      >%h=();
      >foreach (\%h1, \%h2) {
      >  while (($a, $b)=each(%$_)) {
      >    push @{$h{$a}}, $b
      >  }
      >}

      ага, спасибо за подсказку, вроде получается
      foreach $k (sort keys %h){print "$k: @{$h{$k}}\n"                                                                           }

  • Хэш массивов, !*! ACCA, 01:52 , 06-Апр-07 (2)
    >$hash{$ident_total}=@array, где @array=(hash1{$ident},hash2{$ident}) и если значения
    > отсутствуют, то просто ноль.

    Насколько нужно хранить раздельные значения? Нельзя просто сложить их, если они числовые?

    foreach $h (\%hash1 \%hash2 ...) {
         foreach $k (keys %{ $h }) {
             $$h{$k} =~ /clean up regex/;
             $global_stat{$k} += $1;   # ну, или что там ты получил
         }
    }

    • Хэш массивов, !*! Cyrus_user, 09:05 , 06-Апр-07 (4)
      >>$hash{$ident_total}=@array, где @array=(hash1{$ident},hash2{$ident}) и если значения
      >> отсутствуют, то просто ноль.
      >
      >Насколько нужно хранить раздельные значения? Нельзя просто сложить их, если они числовые?

      Хранить обязательно, складывать нельзя. Возможно я сначала сумбурно обьяснил, попытаюсь заново, на простом примере:
      получаю 2 хэша такого содержения.
      %h_in{$user_mail}=$messages_in #получено сообщений
      %h_out{$user_mail}=$messages_out #отправлено сообщений
      какой-то конкретный $user_mail может отсутствовать в одном из кэшей, если он не полуали или не отправлял сообщения.

      Хочу получить новый хэш, где ключ $user_mail, а значение @data=($messages_in,messages_out)
      причём если значения нет (ключ+значение отсутствует в одном из кэшей) то в массив всё равно ставим 0.

      >foreach $h (\%hash1 \%hash2 ...) {
      >     foreach $k (keys %{ $h }) {
      >
      >         $$h{$k} =~ /clean up regex/;
      >         $global_stat{$k} += $1;
      >  # ну, или что там ты получил
      >     }
      >}

      в принципе A мне показал как это делать, на ваш пример заставил задуматься, а так ли мне нужен массив в значениях, проще будет в дальнейщем работать со строкой, которую получу из сложения значений в хэшах как строк, а не чисел. что-то типа $global_stat{$k} .= $$h{$k};

  • Хэш массивов, !*! Cyrus_user, 12:54 , 06-Апр-07 (5)
    у меня ещё вопрос по хэшам:
    как посмотреть определённый ключ по конкретному значению без цикла перебора всего хэша?

    допустим есть готовый хэш вида $h1{$mail}=$uid ключ $mail, значение $uid
    в цикле ниже я заполняю другой хэш $h2{$mail}=$var из строки где всегда присутствует $uid, но не всегда $mail. мне же ключом нужен именно $mail.
    тогда, если при разборе не удалось выяснить $mail, но известен $uid то я хочу сделать так:
    $h2{где ключ, ключ из $h1 полученный по значению $uid}=$var
    вот тут и застрял :( делать reverse %h1 нельзя, потому что uid уникален

    если это невозможно, придётся изобретать конструкцию замены названий ключей в %h2

    • Хэш массивов, !*! A, 14:18 , 06-Апр-07 (6)
      я, честно говоря, не смог понять что надо :-) тут нигде опечатка не закралась?
      • Хэш массивов, !*! Cyrus_user, 06:25 , 09-Апр-07 (7)
        >я, честно говоря, не смог понять что надо :-) тут нигде опечатка
        >не закралась?

        ммм, попробую ещё раз c примером.

        есть готовый хэш вида $h1{cyrus@domen.ru}=cyrus_user в переменных так: $h1{$mail}=$uid
        далее, другой хэш заполняю в такой виде $h2{cyrus@domen.ru}='какое-то значение' (в переменных: $h2{$mail}=$size).

        заполнение %h2 идёт из такой строки
        mail=cyrus@domen.ru uid=cyrus size=123
        где берутся $mail и $size

        однако, строка может принять вид:
        mail=<> uid=cyrus size=123

        тогда, чтобы получить $mail, нужно в %h1 найти по $uid ключ $mail и подставить полученный ключ $mail, как ключ в %h2. вот что-то такое:
        $h2{где ключ, значение ключа из %h1 полученный по значению $uid}=$size

        • Хэш массивов, !*! A, 09:21 , 09-Апр-07 (8)
          кажется понял :-)
          а почему вы пишите
          > делать reverse %h1 нельзя, потому что uid уникален
          как раз с уникальным-то можно
          • Хэш массивов, !*! Cyrus_user, 10:09 , 09-Апр-07 (9)
            >кажется понял :-)
            >а почему вы пишите
            >> делать reverse %h1 нельзя, потому что uid уникален
            >как раз с уникальным-то можно

            уникальный то он для задачи..

            #ключ $mail, значение $uid
            my %h1=('cyrus@domen.ru' => 'cyrus',                                                                                    
                    'admin@domen.ru' => 'cyrus');                                                                                  
            my %h2=reverse %h1;                                                                                                    
            while(($key,$value) = each %h1){print "$key -> $value\n";}                                                              
            while(($key,$value) = each %h2){print "$key => $value\n";}                                                              

            $ ./2test.pl
            cyrus@domen.ru -> cyrus
            admin@domen.ru -> cyrus
            cyrus => cyrus@domen.ru

            если сделаю reverse, тоесть значения станут ключами и наоборот, то тогда в данной хэше повторяющийся ключ $uid будет иметь только одно значение (какое-то там по индексам хэша, сам перл придумает).

            • Хэш массивов, !*! Cyrus_user, 10:33 , 09-Апр-07 (10)
              >>кажется понял :-)
              >>а почему вы пишите
              >>> делать reverse %h1 нельзя, потому что uid уникален
              >>как раз с уникальным-то можно
              >
              >уникальный то он для задачи..
              >
              >#ключ $mail, значение $uid
              >my %h1=('cyrus@domen.ru' => 'cyrus',                                                                                    
              >        'admin@domen.ru' => 'cyrus');                                                                                  
              >my %h2=reverse %h1;
              >while(($key,$value) = each %h1){print "$key -> $value\n";}                                                              
              >while(($key,$value) = each %h2){print "$key => $value\n";}                                                              
              >
              >$ ./2test.pl
              >cyrus@domen.ru -> cyrus
              >admin@domen.ru -> cyrus
              >cyrus => cyrus@domen.ru
              >
              >если сделаю reverse, тоесть значения станут ключами и наоборот, то тогда в
              >данной хэше повторяющийся ключ $uid будет иметь только одно значение (какое-то
              >там по индексам хэша, сам перл придумает).

              хотя тут я опять стал думать в контексте задачи..
              если поле mail пустое, то не всё ли равно какой mail по uid подставлять? ;)

              в конечной статистике оперирование пойдёт по $uid-ам и их привязке к отделам.
              вообщем всю концепцию переработаю, но вопрос остаётся в силе.

              заполнение %h3 идёт из такой строки
              mail=cyrus@domen.ru uid=cyrus size=123
              где берутся $mail, $uid и $size
              однако, строка может принять вид:
              mail=<> uid=cyrus size=123
              тогда я хочу вот так (выше для %h2 сделал reverse):
              if ($mail "<>") {
              $h3{$h2{$uid}}+=$size;
              }          
              на что получаю:
              Use of uninitialized value in concatenation (.) or string

              вот собственно как в %h3 сделать ключом значение, полученное из %h2 по ключу?
              равно как и первоначальная задача была в %h3 сделать ключом ключ из %h1, полученный по значению.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру