http://qs1969.pair.com?node_id=11140690

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

Happy January fellow Monks

I've written some code that works...but I don't like it!

Not only is it a bit messy, it also is probably not as efficient as it could be although it is only handle small amounts of data. But the main problem is that it uses Perl's smart match operator. I am using Perl 5.16.3 and smart match works well for what I want under this version. But I cannot guarantee it will always be using this version so don't want to stop it from being forward compatible.

Here's the bare bones of the code:

my $query = $dbh->prepare("SELECT * FROM Sector, Lane_has_Sector WHERE + Sector_idSector = idSector AND Lane_wid = ? ORDER BY metric"); $query->execute($wid); while (my $sec = $query->fetchrow_hashref) { # More stuff happens here... ($sec->{'authority'}, my $prefix, my $suffix) = $dbh->selectrow_ar +ray("SELECT name, prefix, suffix FROM Authority WHERE idAuthority = ? +", undef, $sec->{'Authority_idAuthority'}); $prefix = "$prefix " if $prefix; $suffix = " $suffix" if $suffix; push @authority, $prefix . $sec->{'authority'} . $suffix unless $p +refix . $sec->{'authority'} . $suffix ~~ @authority; } my $auth_list = join '<br>', @authority;
Essentially I am pulling data from a database. Collecting together a some information into the @authority array but I only want unique values. This strikes me as the sort of thing databases are good at so I could hit the database again with another query that's quantified as DISTINCT and build my @authority array from that. But that seems messy as well. In the vast majority of cases, @authority will only hold one value but there are few times when it will hold two, perhaps three.

I'm thinking grep or List::Util might be a more elegant and robust solution here.

Any suggestions would be very welcome...

Replies are listed 'Best First'.
Re: Alternative to smart match
by LanX (Saint) on Jan 22, 2022 at 01:12 UTC
    I think you want a %seen hash

    push @authority, $full unless $seen{$full}++;

    if order doesn't matter you just built up %seen and do @authority = keys %seen at the end.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      I think you want a %seen hash

      I think you right!

      Clearly I was overthinking it and missing the obvious...I don't even need the @authority array as I can build the output string directly from the hash keys

      my $auth_list = join '<br>', keys %seen;
      Thanks Rolf

        Great, your welcome.

        But please keep in mind that hashes are randomized in Perl, hence you can't rely on the order.

        If it's meant for display in HTML you might want to sort them first.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery