0

I have this code, and I'm getting the warning: Argument "" isn't numeric in numeric eq (==) for $id == $_

@delete has numbers coming from a web-form(CGI request), and probably that's why perl is treating those numbers as strings. It's working fine but I don't know what to do about the warnings.

my @IDs =  (21, 36, 6, 7, 64, 6435, 24);
for my $id (@IDs) {
    push @insert, $id if (grep $id == $_, @delete)
}

I don't want the warnings. What is my best option?

I first thought of iterating over the array and calling int for every element, but I didn't like the idea.

4

3 回答 3

3

如果 0 不是有效 ID,请使用如下 grep 语法:

grep { $_ and ($id == $_) } @delete;

或者,如果 $_ 只有数字,则匹配:

grep { /\d+/ and ($id == $_) } @delete;
于 2013-07-29T08:25:41.250 回答
2

快速演示您的问题:

use strict;
use warnings;

my @insert;
my @IDs =  (21, 36, 6, 7, 64, 6435, 24);

my @delete = split / /, "1 2 4";
warn "this is ok";
for my $id (@IDs) { push @insert, $id if (grep { $id == $_ } @delete) }

warn "now get warning";
@delete = split / /, "1 2  4";
#                        ^^ note two spaces - the split will produce one empty element
for my $id (@IDs) { push @insert, $id if (grep { $id == $_ } @delete) }

您只需要验证数字的输入。

于 2013-07-29T08:49:33.620 回答
2

...这就是为什么 perl 将这些数字视为字符串

不,由于数字相等运算符,Perl 将您的数据转换为数字==。当它发出警告时"",表示您有一个空字符串,它将被转换为零0。换句话说,您的@delete数组包含一个空元素。

您可能应该做的是使用哈希:

my @IDs = (21, 36, 6, 7, 64, 6435, 24);
my %ID  = map { $_ => 1 } @IDs;
my @insert = grep $ID{$_}, @delete;

这将避免任何转换,这可能是好事也可能是坏事。一方面,它不会将空字符串转换为零,但它也不会将字符串转换" 12"为数字12

你的空字符串问题仍然存在,但只要你没有空字符串的键,你就可以了。

此外,您应该记住为什么它们被称为“警告”。它们在那里表明您正在做一些不太正确的事情。因此,仅仅在不知道原因的情况下使警告静音是一件非常糟糕的事情。在这种情况下,您应该特别弄清楚您想对空字符串值做什么。(以及其他可能的坏值)。

您可以通过执行以下操作从数组中删除空字符串值:

@delete = grep !/^$/, @delete;
于 2013-07-29T08:41:23.147 回答