Home > Archive > PERL CGI Beginners > March 2006 > checking existance of an item in an array
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
checking existance of an item in an array
|
|
| Konstantine 2006-02-08, 8:53 am |
| R3JlZXRpbmdzCgpUaGlzIGlzIG15IGZpcnN0IHN0
YWIgYXQgUGVybC4gUGxlYXNlIGJlIGdlbnRs
ZSA6LSkKCkkgaGF2ZSB0aGUgZm9sbG93aW5nIHNu
aXBwZXQgd2hpY2ggc2VlbXMgdG8gZG8gd2hh
dCBJIGFtIHRyeWluZyB0byBkbywKbmFtZWx5LCBj
aGVjayB0aGUgdXJsIGZpZWxkIHZhbHVlIGlu
IGEgUE9TVCByZXF1ZXN0LCBkbyBhIHNlcnZlcgpy
ZWRpcmVjdCAoYXMgb3Bwb3NlZCB0byBicm93
c2VyIHJlZGlyZWN0KSBpZiB0aGUgdmFsdWUgaXMg
aW4Kc2FmZV9kZXN0aW5hdGlvbnMgYXJyYXks
IHJlZGlyZWN0IHRvIHN0YXJ0Lmh0bSBpZiBub3Qu
CgojIS91c3IvYmluL3BlcmwgLXdUCiMKdXNl
IHN0cmljdDsKdXNlIENHSSBxdyg6c3RhbmRhcmQp
OwpteSBAc2FmZV9kZXN0aW5hdGlvbnMgPSAo
J2EuaHRtJywgJ2IuaHRtJywgJ2MuaHRtJyk7Cm15
ICRkZXN0aW5hdGlvbl91cmwgPSAnL3N0YXJ0
Lmh0bSc7CmlmKHBhcmFtKCkpIHsKCWZvcmVhY2gg
KEBzYWZlX2Rlc3RpbmF0aW9ucykgewoJCWlm
IChwYXJhbSgndXJsJykgZXEgJF8pIHsKCQkJJGRl
c3RpbmF0aW9uX3VybCA9ICcvJyAuIHBhcmFt
KCd1cmwnKTsKCQkJbGFzdDsKCQl9Cgl9CQp9CnBy
aW50IHJlZGlyZWN0KCRkZXN0aW5hdGlvbl91
cmwpOwoKSSBoYXZlIHR3byBxdWVzdGlvbnMKSXMg
dGhlcmUgYSBmdW5jdGlvbiB0byBjaGVjayBp
ZiBhbiBpdGVtIGlzIGluIGFuIGFycmF5LCBpbnN0
ZWFkIG9mCmxvb3BpbmcgdGhyb3VnaCB0aGUg
YXJyYXk/ IENhbiB5b3Ugc2VlIGEgcHJvYmxlbSB3aXRoIHRo
ZSBzbmlwcGV0PwpNYW55IHRoYW5r
cyBmb3IgeW91ciB0aW1lLgpLLgo=
| |
|
| --- Konstantine <listclient@gmail.com> wrote:
> Greetings
>
> This is my first stab at Perl. Please be gentle :-)
>
> I have the following snippet which seems to do what I am trying to
> do,
> namely, check the url field value in a POST request, do a server
> redirect (as opposed to browser redirect) if the value is in
> safe_destinations array, redirect to start.htm if not.
>
> #!/usr/bin/perl -wT
> #
> use strict;
> use CGI qw(:standard);
> my @safe_destinations = ('a.htm', 'b.htm', 'c.htm');
> my $destination_url = '/start.htm';
> if(param()) {
> foreach (@safe_destinations) {
> if (param('url') eq $_) {
> $destination_url = '/' . param('url');
> last;
> }
> }
> }
> print redirect($destination_url);
>
> I have two questions
> Is there a function to check if an item is in an array, instead of
> looping through the array? Can you see a problem with the snippet?
> Many thanks for your time.
Typically this is done by putting the array elements in a hash. Here's
how one might write this:
my %safe_destination
= map { $_ => 1 } ('a.htm', 'b.htm', 'c.htm');
my $destination_url = '/start.htm';
if ( my $url = param('url') ) {
if ( exists $safe_destination{$url} ) {
$destination_url = "/$url";
}
}
Since you're new to Perl, the map statement will look weird. You might
find it clearer to do this (and this will create the same data
structure as the map statement):
my %safe_destination = (
'a.htm' => 1,
'b.htm' => 1,
'c.htm' => 1,
);
In this case, the values are irrelevant. We're just using a hash as a
lookup table.
Cheers,
Ovid
--
If this message is a response to a question on a mailing list, please send follow up questions to the list.
Web Programming with Perl -- http://users.easystreet.com/ovid/cgi_course/
| |
| mnagaraj@gmail.com 2006-03-02, 6:55 pm |
| A more simpler way to do this would be to do a join on the array and do
a regex comparison:
if (join(',', @array) =~ $item)
{
print "found";
}
else
{
print "not found";
};
| |
| Paul Lalli 2006-03-03, 7:55 am |
| mnagaraj@gmail.com wrote:
> A more simpler way to do this would be to do a join on the array and do
> a regex comparison:
Yes it would. Unfortunately, it would also be incorrect.
> if (join(',', @array) =~ $item)
> {
> print "found";
> }
> else
> {
> print "not found";
> };
@array = ('foobar', 'baz');
$item = 'foo';
What does your method return?
Paul Lalli
| |
| mnagaraj@gmail.com 2006-03-03, 6:55 pm |
| Paul,
Yes, a verbatim reproduction would produce the error you mention...
But the whole idea of putting in a seperator in the join is to use it
as a word-demarcator. so if you tried to match the pattern ',foo,', for
instance, you wouldn't find it...
I'll let you be creative on the error-conditions...the frameowrk is
still the simplest :)
-mouli
| |
| mnagaraj@gmail.com 2006-03-03, 6:55 pm |
| BTW, if you have larger lists to check membership in, my friend
Mattisse informs me that there is a function "any" in List::MoreUtils
that may be more fast and simpler:
any { $item eq $_} @array --- would return true if $item is in
$array ($_ iterates over $array)
-mouli.
| |
| Paul Lalli 2006-03-03, 6:55 pm |
| mnagaraj@gmail.com wrote:
> Paul,
> Yes, a verbatim reproduction would produce the error you mention...
>
> But the whole idea of putting in a seperator in the join is to use it
> as a word-demarcator. so if you tried to match the pattern ',foo,', for
> instance, you wouldn't find it...
>
> I'll let you be creative on the error-conditions...the frameowrk is
> still the simplest :)
Infinitely better to be complicated and correct than simple and wrong.
Your method still breaks if the array elements contain commas. The
hash method does not.
Paul Lalli
| |
| Paul Lalli 2006-03-03, 6:55 pm |
| mnagaraj@gmail.com wrote:
> BTW, if you have larger lists to check membership in, my friend
> Mattisse informs me that there is a function "any" in List::MoreUtils
> that may be more fast and simpler:
>
> any { $item eq $_} @array --- would return true if $item is in
> $array ($_ iterates over $array)
which, non-surprisingly, is precisely what the FAQ recommends if you
are not going to be repeatedly making this check. (It doesn't say to
use List::MoreUtils::any specifically - it says to iterate over the
array and returning from the loop as soon as you find the element).
perldoc -q contains
or
perldoc -q contained
depending on your Perl version.
Paul Lalli
| |
| mnagaraj@gmail.com 2006-03-03, 6:55 pm |
| Point well taken...
-mouli.
|
|
|
|
|