Yadheendran Yadheendran - 1 month ago 4
Perl Question

Perl find out if X is an element in an array

I don't know why small things are too not working for me in Perl. I am sorry for that.

I have been trying it around 2 hrs but i couldn't get the results.

my $technologies = 'json.jquery..,php.linux.';
my @techarray = split(',',$technologies);

#my @techarray = [
# 'json.jquery..',
# 'php.linux.'
# ];

my $search_id = 'json.jquery..';

check_val(@techarray, $search_id);


And i am doing a "if" to search the above item in array. but it is not working for me.

sub check_val{
my @techarray = shift;
my $search_id = shift;
if (grep {$_ eq $search_id} @techarray) {
print "It is there \n";
}else{
print "It is not there \n";
}
}


Output: It always going to else condition and returns "It is not there!" :(

Any idea. Am i done with any stupid mistakes?

Answer

You have an arrayref there, by using [ .... ] (an anonymous array really). An array would be defined by using ( ... ). Also, when you assing that arrayref to an array, you are assigning to an element of the array, since a reference is a scalar. It is like my @arr = 'a';.

An easy fix is to either define an array, my @techarray = ( ... ), or to properly define an arrayref and then dereference when you search

my $rtecharray = [ .... ];
if (grep {$_ eq $search_id} @$rtecharray) {
    # ....
}

For all kinds of list manipulations have a look at List::Util and List::MoreUtils.


Updated to changes in the question, as the sub was added

This has something else, which is more instructive.

As you pass an array to a function it is passed as a flat list of its elements. Then in the function the first shift picks up the first element, and then the second shift picks up the second one.

Then the search is over the array with only 'json.jquery..' element, for 'php.linux.' string.

Instead, you can either pass a reference,

check_val(\@techarray, $search_id);

and use it as such in the function, or (if you pass the array) get arguments in the function as

my (@array, $search_id) = @_; 

In general I'd recommend passing lists by reference.

Comments