hash generation question

Ask a Question related to PERL Modules, Design and Development.

  1. #1

    Default Re: hash generation question

    Stephan wrote:
    [...]
    > For example, suppose I have this:
    >
    > @list1 = qw(x1 x2 x3 data);
    >
    > How can I generate an hash like
    >
    > hash{x1}{x2}{x3} = data ?
    >
    > The only thing I could come up with is to generate the above line and
    > eval it but I'd guess there must be a more clean way to deal with
    > this?
    How's this related to the modules list?

    Anyhow, what about this:

    my $hashref = \%hash;
    $hashref = $hashref->{$_} foreach @list1[0..$#list1-2];
    $hashref->{$list1[-2]} = $list1[-1];

    Steffen
    --
    *_=*DATA;seek+_,0,0;print<_>;
    __DATA__
    What's a quine?

    Steffen Müller Guest

  2. Similar Questions and Discussions

    1. Simple Hash Question
      Hi .... I have a hash defined as my %flag3 = ( A => "DBSpace backup thread", B => "Begin work", C => "Commiting/committed", H => "Heuristic...
    2. [PHP-DEV] hash table question
      For my upcoming improvement of interbase.c, which features asynchronous handling of events posted in the database, I need to maintain a per-link...
    3. Another reference question (hash of hash references)
      beginners, I am trying to build a hash of hash references. My problem is that I need to be able to add a key/value pair to the internal hashes......
    4. Proposal: Array#to_h, to simplify hash generation
      Hi -talk, Ruby has wonderful support for chewing and spitting arrays. For instance, it's easy to produce an array from any Enumerable using...
    5. Big hash question
      I have a very large hash inside a script. The $values of the $keys can be very large. When the script runs, it takes a long time to load the...
  3. #2

    Default Re: hash generation question

    Steffen Müller <sv99oya02@sneakemail.com> writes:
    > Stephan wrote:
    > [...]
    > > For example, suppose I have this:
    > > @list1 = qw(x1 x2 x3 data);
    > > How can I generate an hash like
    > > hash{x1}{x2}{x3} = data ?
    > > The only thing I could come up with is to generate the above line and
    > > eval it but I'd guess there must be a more clean way to deal with
    > > this?
    >
    > How's this related to the modules list?
    >
    > Anyhow, what about this:
    >
    > my $hashref = \%hash;
    > $hashref = $hashref->{$_} foreach @list1[0..$#list1-2];
    Did you test this loop?

    What would you expect to happen if %hash is empty initially?

    $hashref->{$_} is undef in this case, and all iterations keep
    setting $hashref to an undefined value.

    In short: It does not work at all.
    --
    Cheers,
    haj
    Harald Joerg Guest

  4. #3

    Default Re: hash generation question

    Stephan <stephanj@NOSPAMsci.kun.nl> writes:
    > I'm trying to build a hash structure on the fly without knowledge about
    > depts in my program. (aka userinput)
    >
    > For example, suppose I have this:
    >
    > @list1 = qw(x1 x2 x3 data);
    The "1" in the variable name suggests that you would like to merge more
    than one list in one hash. Is that correct?
    > How can I generate an hash like
    >
    > hash{x1}{x2}{x3} = data ?
    >
    > The only thing I could come up with is to generate the above line and eval
    > it but I'd guess there must be a more clean way to deal with this?
    After reviewing my code below, I thought: How ugly. Perhaps eval isn't
    that bad for the problem.

    Then, on second thought: If you use eval, you might want to be prepared
    for crafted user input which tries to break your program's security.
    There is no easy way to eval strings containing user input.

    So you might want to give it a try....
    ----------------------------------------------------------------------
    #!perl -w
    use strict;

    use Data::Dumper;

    my @lists = ([qw(x1 x2 x3 data)]
    ,[qw(x1 x2 prunes_previous_hash)]
    ,[qw(tooshort)]
    ,[qw(y1 dada)]
    ,[qw(y1 replaces scalar by hash)]
    ,[undef,undef,'undef gives warnings']
    );
    my %hash = ();

    for my $list (@lists) {
    my $r_h = \%hash;
    unless (scalar @$list >= 2) {
    warn "skipping a list with less than two elements";
    next;
    }
    my ($last,$value) = splice @$list,-2;
    for (@$list) {
    $r_h->{$_} = {} unless (ref $r_h->{$_} eq 'HASH');
    $r_h = $r_h->{$_};
    }
    $r_h->{$last} = $value;
    }

    print Dumper(\%hash);
    ----------------------------------------------------------------------
    --
    Good luck,
    haj
    Harald Joerg Guest

  5. #4

    Default Re: hash generation question

    Harald Joerg wrote:
    >>my $hashref = \%hash;
    >>$hashref = $hashref->{$_} foreach @list1[0..$#list1-2];
    > Did you test this loop?
    No, obviously. So make it:

    my $hashref = \%hash;
    foreach (@list1[0..$#list1-2]) {
    $hashref->{$_} = {} unless ref($hashref->{$_}) eq 'HASH';
    $hashref = $hashref->{$_};
    }

    $hashref->{$list1[-2]} = $list1[-1];

    Again. Untested. Sue me.
    --
    @n=([283488072,6076],[2105905181,8583184],[1823729722,9282996],[281232,
    1312416],[1823790605,791604],[2104676663,884944]);$b=6;@c=' -/\_|'=~/./g
    ;for(@n){for$n(@$_){map{$h=int$n/$b**$_;$n-=$b**$_*$h;$c[@c]=$h}reverse
    0..11;push@p,map{$c[$_]}@c[reverse$b..$#c];$#c=$b-1}$p[@p]="\n"}print@p;

    Steffen Müller Guest

  6. #5

    Default Re: hash generation question

    In article <bdmdt1$lt7$1@wnnews.sci.kun.nl>
    Stephan <stephanj@NOSPAMsci.kun.nl> wrote:
    >>> @list1 = qw(x1 x2 x3 data);
    >>
    >> The "1" in the variable name suggests that you would like to merge more
    >> than one list in one hash. Is that correct?
    >>
    >>> How can I generate an hash like
    >>>
    >>> hash{x1}{x2}{x3} = data ?
    >>>
    >>> The only thing I could come up with is to generate the above line and eval
    >>> it but I'd guess there must be a more clean way to deal with this?
    >
    > Totally correct, so (x1 x2 x4 data) etc in the same hash.
    >>
    >> After reviewing my code below, I thought: How ugly. Perhaps eval isn't
    >> that bad for the problem.
    >>
    >> Then, on second thought: If you use eval, you might want to be prepared
    >> for crafted user input which tries to break your program's security.
    >> There is no easy way to eval strings containing user input.
    >
    > The ", \ etc problems. I've escaped around those 2. The userinput is my own,
    > so I can avoid most trapholes.
    >
    >> my ($last,$value) = splice @$list,-2;
    >> for (@$list) {
    >> $r_h->{$_} = {} unless (ref $r_h->{$_} eq 'HASH');
    >> $r_h = $r_h->{$_};
    >> }
    >> $r_h->{$last} = $value;
    >> }
    >
    > This seems to work like expected. Just funny that such a simple problem
    > doesn't really have a clean, nice perl way.
    >
    > Stephan
    Recursion can be your friend:

    my @list1 = qw(x1 x2 x3 data);
    my $hash = build( 0, \@list1 );

    sub build {
    my ( $i, $list ) = @_;
    my $key = $list->[ $i++ ];
    return { $key => $i < 3 ? build( $i, $list ) : $list->[$i] };
    }

    print $$hash{x1}{x2}{x3};

    Jimbo.



    Jimbo@Jimbo.com Guest

  7. #6

    Default Re: hash generation question

    Stephan wrote:
    [snip]
    > This seems to work like expected. Just funny that such a simple
    > problem doesn't really have a clean, nice perl way.
    What's so unsimple about:

    my $ref = \\%hash;
    $ref = \$$ref->{$_} for @list1[0 .. $#list-1];
    $$ref = $list[-1];

    --
    $a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca
    );{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "$@[$a%6
    ]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}
    Benjamin Goldberg Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139