Re: Is there a shorter, more elegant way to write this deep hash lookup statement

Discussion in 'Perl Misc' started by Ted Zlatanov, Feb 21, 2013.

  1. Ted Zlatanov

    Ted Zlatanov Guest

    On Sat, 16 Feb 2013 18:16:33 -0600 Ignoramus329 <ignoramus329@NOSPAM.329.invalid> wrote:

    I> As I always say 'use strict; use warnings', I have this statement in my program:
    I> $is_freight = 1
    I> if $ebay_record
    I> && $ebay_record->{ShippingDetails}
    I> && $ebay_record->{ShippingDetails}->{ShippingServiceOptions}
    I> && $ebay_record->{ShippingDetails}->{ShippingServiceOptions}->{ShippingService}
    I> && $ebay_record->{ShippingDetails}->{ShippingServiceOptions}->{ShippingService} eq 'Freight';

    I> This is a correct statement and it does not give errors or warnings,
    I> however, I would like to know if I can write it in a shorter way.

    I have a function to do this, which recursively searches a hashref. It
    has some array search logic as well; just remove the second part if you
    don't want that (I needed it for parsing some XML data). You could use
    Data::Match instead, but it's really not a difficult task either way,
    and I like my interface better.

    You call it like this for your case:

    hashref_search($ref, qw/ShippingDetails ShippingServiceOptions ShippingService/);

    and just check that the return is defined and equal to 'Freight'.

    Hope that helps...
    Ted

    #+begin_src perl
    sub hashref_search
    {
    my $ref = shift @_;
    my $k = shift @_;
    if (ref $ref eq 'HASH' && exists $ref->{$k})
    {
    if (scalar @_ > 0) # dig further
    {
    return hashref_search($ref->{$k}, @_);
    }
    else
    {
    return $ref->{$k};
    }
    }

    if (ref $ref eq 'ARRAY' && ref $k eq 'HASH') # search an array
    {
    foreach my $item (@$ref)
    {
    foreach my $probe (keys %$k)
    {
    if (ref $item eq 'HASH' &&
    exists $item->{$probe})
    {
    # if the value is undef...
    return $item unless defined $k->{$probe};
    # or it matches the probe
    return $item if $item->{$probe} eq $k->{$probe};
    }
    }
    }
    }

    return undef;
    }

    #+end_src
     
    Ted Zlatanov, Feb 21, 2013
    #1
    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. Kamilche
    Replies:
    7
    Views:
    292
    Peter Hansen
    Jun 29, 2004
  2. dblock
    Replies:
    2
    Views:
    663
    Simon Krahnke
    Oct 9, 2011
  3. Dr.Ruud
    Replies:
    1
    Views:
    174
    Ted Zlatanov
    Feb 21, 2013
  4. George Mpouras
    Replies:
    0
    Views:
    161
    George Mpouras
    Feb 17, 2013
  5. C.DeRykus
    Replies:
    0
    Views:
    146
    C.DeRykus
    Feb 19, 2013
Loading...

Share This Page