matching array element to hash key

Discussion in 'Perl Misc' started by ccc31807, Sep 17, 2009.

  1. ccc31807

    ccc31807 Guest

    This is probably a real stupid question, but it's late and I'm running
    behind, and quite frankly have run out of mental energy.

    I have an array with about 5,000 elements that looks like this:
    0002793 0005095 0093350 0134143 0145740 0146854 0150248 0151827
    0156424 0161321 0186959 0198460 0218115

    I have a four level hash that looks like this:
    $hash{$s}{$l}{$h}{$id} = $terms
    This has contains about 8,000 discrete elements.

    The $id key in the hash either matches an array element or it does
    not. I need to write the hash keys and the values to one file if the
    $id matches the array element. I need to write the unmatching array
    elements to a second file, and the unmatching hash elements to a third
    file.

    Here's what I'm trying to do:

    foreach my $sid (@array)
    {
    if ($sid == ???)
    {
    print FIRST qq($s $l $h $id $hash{$s}{$l}{$h}{$id}\n);
    delete $hash{$s}{$l}{$h}{$id};
    shift @array;
    }
    }
    foreach (@array) { print SECOND qq{$_\n); }

    Then, print the remaining hash elements to THIRD

    I'm sorry, but for the life of me I can't figure out how to access the
    last level of the hash, at least without iterating through the hash.

    CC.
     
    ccc31807, Sep 17, 2009
    #1
    1. Advertising

  2. ccc31807

    Guest

    On Thu, 17 Sep 2009 13:23:43 -0700 (PDT), ccc31807 <> wrote:

    >This is probably a real stupid question, but it's late and I'm running
    >behind, and quite frankly have run out of mental energy.
    >
    >I have an array with about 5,000 elements that looks like this:
    >0002793 0005095 0093350 0134143 0145740 0146854 0150248 0151827
    >0156424 0161321 0186959 0198460 0218115
    >
    >I have a four level hash that looks like this:
    >$hash{$s}{$l}{$h}{$id} = $terms
    >This has contains about 8,000 discrete elements.
    >
    >The $id key in the hash either matches an array element or it does
    >not. I need to write the hash keys and the values to one file if the
    >$id matches the array element. I need to write the unmatching array
    >elements to a second file, and the unmatching hash elements to a third
    >file.
    >
    >Here's what I'm trying to do:
    >
    >foreach my $sid (@array)
    >{
    > if ($sid == ???)
    > {
    > print FIRST qq($s $l $h $id $hash{$s}{$l}{$h}{$id}\n);
    > delete $hash{$s}{$l}{$h}{$id};
    > shift @array;
    > }
    >}
    >foreach (@array) { print SECOND qq{$_\n); }
    >
    >Then, print the remaining hash elements to THIRD
    >
    >I'm sorry, but for the life of me I can't figure out how to access the
    >last level of the hash, at least without iterating through the hash.
    >
    >CC.


    There is no shame in itterating.

    -sln
    =====================
    use strict;
    use warnings;

    my %hash = (
    s1 => {
    l1 => {
    h1 => {
    id01 => 9487,
    id02 => 9488,
    bad => { id2a => 666 }
    },
    h2 => {
    id03 => 9489,
    id04 => 9490
    }
    },
    l2 => {
    h3 => {
    id05 => 9491,
    id06 => 9492
    },
    h4 => {
    id07 => 9493,
    id08 => 9494
    }
    }
    },
    s2 => {
    l3 => {
    h5 => {
    id09 => 9495,
    id10 => 9496,
    bad => { id10a => 666 }
    },
    h6 => {
    id11 => 9497,
    id12 => 9498
    }
    },
    bad => 3982
    }
    );


    my $level = 0;
    my @keystack = ();
    my @found = ();

    _GVM(\%hash);

    print "$_\n" for sort @found;

    exit 0;


    sub _GVM {
    my $var = shift;
    return if ( ref ($var) ne 'HASH');

    for (keys %{$var})
    {
    push @keystack, $_;
    if (ref ($var->{$_}) eq 'HASH') {
    _GVM ($var->{$_}) if ++$level < 4;
    --$level;
    }
    elsif (ref (\$var->{$_}) eq 'SCALAR' && $level == 3) {
    push @found, "@keystack $var->{$_}";
    #print "@keystack $var->{$_}\n";
    #print THIRD "@keystack $var->{$_}\n";
    }
    pop @keystack;
    }
    return;
    }


    __END__

    Output:

    s1 l1 h1 id01 9487
    s1 l1 h1 id02 9488
    s1 l1 h2 id03 9489
    s1 l1 h2 id04 9490
    s1 l2 h3 id05 9491
    s1 l2 h3 id06 9492
    s1 l2 h4 id07 9493
    s1 l2 h4 id08 9494
    s2 l3 h5 id09 9495
    s2 l3 h5 id10 9496
    s2 l3 h6 id11 9497
    s2 l3 h6 id12 9498
     
    , Sep 17, 2009
    #2
    1. Advertising

  3. ccc31807

    ccc31807 Guest

    On Sep 17, 6:07 pm, Ben Morrow <> wrote:
    > > I'm sorry, but for the life of me I can't figure out how to access the
    > > last level of the hash, at least without iterating through the hash.

    >
    > You can't. Iterate over the whole structure and build a new hash keyed
    > by $id only (or, obviously, modify whatever code builds %hash to do that
    > in the first place).


    Haste makes waste, as they say. I was trying to do this on the quick
    and dirty. Yes, you are correct, I need to put the IDs from the hash
    into a separate hash. Not only is it not a big deal, it will improve
    my output since I will have access to some details that I was losing
    trying to do it the way I posted.

    > Presumably all your $ids are unique? If they aren't, you will need to
    > decide what to do with the duplicates, but you needed to do that anyway.


    Yes, all the IDs are unique as to the person, but (obviously) not to
    the data sets. This is trouble shooting problem with data from a
    database. The two files are data files that should return exactly the
    same data set, and about 85% of the data is the same. However, the
    data set I'm putting in the hash has about 20% more records that the
    data set I'm putting in the array, and the array has about 30 or 40
    records that are unique to it, and we are trying to discover what the
    difference is that would cause certain records to be returned by one
    query but not the other.

    Thanks, CC.

    >
    > Ben
     
    ccc31807, Sep 18, 2009
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    4
    Views:
    2,630
  2. Victor Bazarov
    Replies:
    15
    Views:
    1,214
    Vaclav Haisman
    Aug 16, 2009
  3. rp
    Replies:
    1
    Views:
    584
    red floyd
    Nov 10, 2011
  4. Une bévue
    Replies:
    5
    Views:
    176
    Une bévue
    Aug 10, 2006
  5. Srijayanth Sridhar
    Replies:
    19
    Views:
    670
    David A. Black
    Jul 2, 2008
Loading...

Share This Page