0

This is sort of what I am wanting to do. At present mm returns nothing, while searchname returns the expected value. This is a perl script embedded in a web page. I have tried numerous approaches to this code but nothing seems to provide the results I desire. I think it is just a case of syntax.

#  search for an item
if ($modtype eq "search") {
    $searchname=$modname;
    print "Value of searchname $searchname\n";
    my @mm = grep{$searchname} @names;
    print "Value of mm @mm\n";

    if ($mm eq $searchname) {
        print "$searchname found!\n";
    }
    else {
        print "$searchname not Found\n";        
    }
}
2
  • Welcome to SO! This example is incomplete--it's not clear what the input array @names is or what $modtype, $searchname etc are. Please provide a minimal reproducible example. Commented Jun 11, 2019 at 20:59
  • I've tidied the formatting of your code. You're welcome, of course, but please consider doing it yourself in the future. Consistent indentation is one of the best tools for making your code readable. And if you're asking a large group of strangers to read your code then it makes sense to make it as easy to understand as possible. Commented Jun 12, 2019 at 14:18

2 Answers 2

4
my @mm = grep { $_ eq $searchname } @names;
if (@mm) {
    print "found\n";
}

grep takes a boolean expression, not just a variable. In that expression, $_ refers to the current list element. By using an equality comparison we get (in @mm) all elements of @names that are equal to $searchname, if any.

To check whether an array is empty, you can simply use it in boolean context, as in if (@mm).

If you don't care about the found elements themselves, just whether there are any, you can use grep in scalar context:

my $count = grep { $_ eq $searchname } @names;
if ($count > 0) {
    print "found $count results\n";
}

This will give you the number of matching elements.

If you don't need to know that number, just whether there was any result at all, you can use any from List::Util:

use List::Util qw(any);

if (any { $_ eq $searchname } @names) {
    ...
}

If @names is big, this is potentially more efficient because it can stop after the first match is found.

I'm not sure what $mm refers to in your code. Did you start your code with use strict; use warnings;? If not, you should.

Sign up to request clarification or add additional context in comments.

2 Comments

Pretty sure your code is working but there seems to be a problem with reading from the array @names so I am looking into that now. It works elsewhere in the code but for some reason returns zero when run from this location. I dont care much for perl code embedded in html but it is what it is.
So the answer was pretty simple. The value being read from the array @names did not match the value in the variable $searchname. I needed to add a "\n" when the $searchname variable is populated with the data from $modname. Neither would have been intuitive with code snippits unless you had access to the data being loaded into the array. Thanks for everyone's help though, it got me looking in the right places.
1

Looks like you misunderstand a couple of things.

my @mm = grep{$searchname} @names;

The grep() function takes two arguments. A block of code ({ $searchname }) and a list of values (@names). For each value in the list, it puts the value into $_ and executes the code block. If the code block returns a true value then the contents of $_ is added to the output list.

Your block of code ignores $_ and just checks for the value of $searchname. That is very likely to always be true, so all of the values from @names get copied into @mm.

I think it's more likely that you want:

my @mm = grep{ $_ eq $searchname } @names;

Secondly, you suddenly start using a new variable called $mm. I suspect you're getting confused between @mm and $mm which are completely different variables with no connection with each other.

I think what you're actually trying to do is to look at the first element of @mm so you want:

if ($mm[0] eq $searchname)

But, given that values only end up in @mm if they are equal to $searchname (because that's what your grep() does), I think you really just want to check whether or not anything ended up in @mm. So you should use:

if (@mm)

Which is, in my opinion, easier to understand.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.