Doozer has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

I am after some advice on the best way to search an array for multiple values sequentially.

My scenario is this:

I have an array with anywhere up to 10 elements. The elements are Wifi Security types such as WPA, WPA2, WEP 64, WEP 128, etc.

What I would like to do is go through the array and select the best available security type according to what is available in the array. The array will differ as I work through different routers, so one router may only support up to WEP 128 while another will have WPA2 available. In my mind, I can see it working in that it will first search the array for WPA2, if it doesnt find it, it will then look for WPA, if thats not found, it will move on to WEP 128, and so on.

I am struggling to think of the best way to handle this. I have a vague idea but I think it will end up being a loooong bit of code with many many if statements and foreach loops.

Any advice would be greatly appreciated and I will happily provide more info if what I have said is not very clear.

Thanks.

  • Comment on Search an array for values sequentially

Replies are listed 'Best First'.
Re: Search an array for values sequentially
by choroba (Cardinal) on May 20, 2014 at 09:20 UTC
    Score the security types in a hash:
    my %score = ( WPA => 1, WPA2 => 2, WEP64 => 3, # ... );

    Than, just search for the maximum. You might need a reversed hash to retrieve the type back from the maximum.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Search an array for values sequentially
by AppleFritter (Vicar) on May 20, 2014 at 09:26 UTC

    I'd use a hash for this rather than an array, something along these lines:

    %supported_security = ( "WPA" => "WPA", "WPA2" => "WPA2", "WEP 64" => "WEP 64", ... );

    And then just probe that hash in order of preference of security type:

    $best_type = $supported_security{"WPA2"} // $supported_security{"WPA"} // $supported_security{"WEP 128"} // ...

    with // being the logical defined-or operator (see Logical Defined Or); if that's not available on the version of Perl you're using, use || instead.

Re: Search an array for values sequentially
by AnomalousMonk (Archbishop) on May 20, 2014 at 12:57 UTC

    Another variation on the "quality scoring" hash:

    c:\@Work\Perl\monks>perl -wMstrict -le "use List::Util qw(reduce); ;; my %quality = qw(WPA2 4 WPA 3 WEP128 2 WEP64 1); ;; my @available = qw(WPA WPA2 WEP128); my $best_available = reduce { $quality{$a} > $quality{$b} ? $a : $b } + @available; print qq{'$best_available' is best available}; " 'WPA2' is best available
Re: Search an array for values sequentially
by Discipulus (Canon) on May 20, 2014 at 09:28 UTC
    is not complicated as you think:
    #untested
    #!perl use strict; use warnings; my @preferred = qw(best good normal bad worst); my @routers = qw (asda adsas asdasds); foreach my $router(@routers){ my $best_of = best_of($router); } sub best_of { my $router = shift; my %available; @available{get_available($router)};# get_available return a list # used as keys of %available ha +sh # for our comfort map { return $_ if exists %avalable{$_} } @preferred; }
    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
      my %available;
      @available{get_available($router)};# get_available return a list
      c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my %h; @h{ qw(a b c) }; dd \%h; " Useless use of hash slice in void context at -e line 1. {} c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my %h; @h{ qw(a b c) } = undef; dd \%h; " { a => undef, b => undef, c => undef }
Re: Search an array for values sequentially
by RichardK (Parson) on May 20, 2014 at 09:30 UTC

    why set up a hash of type => priorities and search your array for the element with the highest priority?

      Thank you all for the quick responses. There are some good methods here which I completely overlooked i.e. using the hash. This looks to be the best solution for what I need but I will have a play and see what works out the best.