Trouble with arrays

D

dima

Has Perl analogue of "in" operator, described bellow?

my @arr = qw/one two three/;
my $elem = "two";
# I need like operator or function
if ($elem in @arr)
{
print "Luck!!!";
}
else
{
print "Sux!!!"
}

I know how write this function:
sub is_in_array($,$)
{
my ($arr_ref, $elem) = @_;
foreach(@{$arr_ref}) {return 1 if ($_ eq $elem);}
return 0;
}
But this is not very good solution!
 
P

Paul Lalli

Stephen said:
Try grep, perldoc -f grep.

No, please do *not* try grep for an "in" operator. Please *do* read
the relevant FAQ on this subject:
perldoc -q contains
Found in /opt/perl/lib/5.6.1/pod/perlfaq4.pod
How can I tell whether a list or array contains a certain
element?

That FAQ will explain to you why you should NOT use grep just to
determine if an element is contained in an array.

Either use the explicit loop-and-return-on-found, convert your
structure to a hash, or use the List::Util function first()
http://search.cpan.org/~gbarr/Scalar-List-Utils-1.17/lib/List/Util.pm

Paul Lalli
 
P

Paul Lalli

In my array only 4 elements!
In this case using grep is not very bed?

No, it's not - in that one particular case. But why would you want to
get into the habbit of using a function that doesn't scale well? This
is not the purpose that grep() was designed for. An important part of
being a good programmer is using the right tool for the right job.
grep() is the wrong tool for this job.

Paul Lalli
 
S

Stephen Hildrey

Paul said:
No, please do *not* try grep for an "in" operator.

I stand corrected!

OP: the loop-and-return of your example is_in_array is
fine; indeed the perlfaq posted by Paul includes a
similar routine:

perldoc> $is_there = 0;
perldoc> foreach $elt (@array) {
perldoc> if ($elt eq $elt_to_find) {
perldoc> $is_there = 1;
perldoc> last;
perldoc> }
perldoc> }
perldoc> if ($is_there) { ... }

Sorry for the poor grep advice!

Cheers,
Steve
 
X

xhoster

Paul Lalli said:
No, please do *not* try grep for an "in" operator. Please *do* read
the relevant FAQ on this subject:
perldoc -q contains
Found in /opt/perl/lib/5.6.1/pod/perlfaq4.pod
How can I tell whether a list or array contains a certain
element?

That FAQ will explain to you why you should NOT use grep just to
determine if an element is contained in an array.

Feh.

Please do not use

($is_there) = grep $_ eq $whatever, @array;

or worse yet

($is_there) = grep /$whatever/, @array;

These are slow (checks every element even if the first
matches), inefficient (same reason), and potentially buggy
(what if there are regex characters in $whatever?).

Feh. Perl is slow and inefficient. Unless you have an unusual structure
to your data-usage, the difference in loops for this operation is on
average a factor of 2. Unless this is in the inner-most loop of your code,
that probably isn't worth batting an eye at. It is not like a difference
between NlnN and N**2. And actually grep might be faster, because the
implicit low-level loop of grep is probably faster than the explicit
Perl-level loop, and because a query not in the array/list requires both
methods to traverse all elements--so if there are a substantial number of
misses, even the theoretical factor of 2 goes out the window. Finally,
grep will generally be inline, while the other way will probably require a
subroutine call with its overhead.


"Potentially buggy"? Yes, if you use a regex to test for equality, which
common sense would tell you not to use, I guess it wouldn't do what you
want. You can screw up any code if you put your mind to it. You could
also put a regex rather than an equality test in the code that the FAQ
recommends. So what?

Either use the explicit loop-and-return-on-found,

7 lines of code to replace 1? What is more likely to have a bug sneak
in?
convert your
structure to a hash, or use the List::Util function first()

I whole heartedly agree on the hash, but List::Util is even more
"potentially buggy". What happens if you search for and find the empty
string?


Xho
 
J

John W. Krahn

Has Perl analogue of "in" operator, described bellow?

my @arr = qw/one two three/;
my $elem = "two";
# I need like operator or function
if ($elem in @arr)
{
print "Luck!!!";
}
else
{
print "Sux!!!"
}


use Quantum::Superpositions;

my @arr = qw/one two three/;
my $elem = "two";

if ($elem eq any @arr)
{
print "Luck!!!";
}
else
{
print "Sux!!!"
}



John
 
W

William James

Has Perl analogue of "in" operator, described bellow?

my @arr = qw/one two three/;
my $elem = "two";
# I need like operator or function
if ($elem in @arr)
{
print "Luck!!!";
}
else
{
print "Sux!!!"
}

In Ruby:

arr = %w/one two three/
elem = "two"
# I need like operator or function
if arr.include?( elem )
print "Luck!!!"
else
print "Sux!!!"
end
 
A

Anno Siegel


[discussion agreed with, snipped]
I whole heartedly agree on the hash, but List::Util is even more
"potentially buggy".

Amen to that. (List::Util in general is okay, but List::Util::first
is seriously broken.)
What happens if you search for and find the empty
string?

That's not the worst case. You can, after all, check for an empty
string. If an undefined value is a possible match, there is *no*
way do distinguish this case from one where there was no match at all.
Both return an undefined value. The no-match case should simply return.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,174
Messages
2,570,940
Members
47,484
Latest member
JackRichard

Latest Threads

Top