So, you need to find matches for a variable in an array? Is the variable a scalar, an array or a hash?
It sounds like you are looking for the first item only.
In the examples below, the built-in grep and first from List::Util are fairly interchangeable. Use grep if you want all the matching items. Use first if you only want the first match. Look at the first two examples, and notice the differences between them to see how to alter subsequent examples to use first.
use strict;
use warnings;
use List::Util qw(first);
my @array_to_search = (1..5) x 2;
my $target_value = 3;
my @target_values = (5, 4);
{ # Find the first target and do something to it.
my $match = first {
$target_value == $_
} @array_to_search;
matches_found( $match );
}
{ # Find all matches and do stuff.
my @matches = grep {
$target_value == $_
} @array_to_search;
matches_found( @matches );
}
{ # match list with nested loop matching
my @matches;
foreach my $target ( @target_values ) {
push @matches, grep {
$target_value == $_
} @array_to_search;
}
matches_found( @matches );
}
{ # match list with a hash lookup
my %target;
@target{ @target_values } = ();
my @matches = grep {
exists $target{$_}
} @array_to_search;
matches_found( @matches );
}
BTW, I noticed a couple of other things in your code that could lead to problems. I've added comments below.
if ($event eq 'JOIN') { # indent your code. It doesn't matter if you
+ use tabs, 2 spaces, or 4 spaces per level, with GNU or K&R or any ot
+her bracketing. Just pick a style and use it.
open (PROTECTED, "$protected");
# two element open. Global file handle in use. No error checking. U
+nnecessary stringification.
@protected = <PROTECTED>; # You are leaving line endings on your list
+ items. Is this what you meant to do? This probably why what you ha
+ve now isn't working.
close(PROTECTED); # no error checking.
for $_ (@protected) { #WTF? No need to add $_ to for declaration.
if ($_ eq $user[0]) {
# Do you really need to override prototypes on your function called s
+ock? &subroutine() has a specific meaning. See perlsub for more info
+. sock() is not very descriptive as function names go. Try somethin
+g like send_message() or send_message_to_client().
&sock("PRIVMSG $tag
:$user[0] Is A Protected User! $_");
# If you want to have multiline variables, use a heredoc. Otherwise c
+onstruct them. Dangling lines like this is asking for trouble.
}
}
}
Same code cleaned up:
if ($event eq 'JOIN') {
# Read in protected user ids
open (my $protected_fh, '<', $protected)
or die "Unable to open $protected: $!\n";
my @protected = <$protected>;
chomp @protected;
close(PROTECTED)
or die "Unable to close $protected: $!\n"
# Verify that $user[0] is not protected.
foreach my $protected_uid (@protected) {
if( $protected_uid eq $user[0] ) {
sock( join "\n",
"PRIVMSG $tag",
'',
":$user[0] Is A Protected User! $protected_uid",
);
last; # stop processing after first match found.
}
}
}
If you aren't already doing so, use strict and warnings. If you are new to Perl and don't recognize the various error messages that these pragmata generate, use diagnostics as well.
Map, grep, first and similar functions are powerful tools that help perl programmers create simple, powerful programs. But good old-fashioned for-loops can do the same jobs--maybe with more typing, maybe a bit less efficiently, but they still get it done. If you don't understand map and friends, study them until you do, but keep using foreach and while in the meantime.
Updated: Fixed error in my code thanks to JadeNB. My error emphasizes my points about using strictures. If I had run this under strict, the error would have been caught by the compiler.
|