2

为了从数组中获取奇数,我得到了这段代码,但不理解一种语法。代码如下

#!/usr/bin/perl

use strict;
use warnings;

# initialize an array
my @array = qw(3 4 5 6 7 8 9);

my @subArray = ();
  foreach (@array) {
  push @subArray, $_ if $_ & 1;
}
print "@subArray\n";
# displays: 3 5 7 9

什么是“如果 $_ & 1” 这是有效的。但我没有得到语法“if $_ & 1”。

类似地,grep 可以像“my @subArray = grep $_ & 1, @array;”一样使用

请帮助我理解语法

4

5 回答 5

4

该行的结构是:

<statement> if <condition>

在哪里和<statement>是。push @subArray, $_<condition>$_ & 1

$_ & 1根据是否设置了的最低位,表达式为 1 或 0 $_。如果是 1(truePerl 中的一个值),则push @subArray, $_执行;否则为 0(falsePerl 中的一个值)并且该语句被跳过。

于 2013-08-11T17:48:47.620 回答
4

是什么 $_ & 1

此表达式分离低位,并且仅设置低位的数字(奇数)

  • $_是默认变量,在这种情况下每个数组元素
  • &是二进制 AND 运算符/按位字符串运算符(将其操作数逐位返回)
  • 1只是一个

  • 请参阅perldoc perlop(乘法运算符)和bit-hacks以获得进一步的解释。

或者,您可以使用模运算符解析偶数/奇数%

使用for循环。

my @odd;
for (@array) {
   push @odd, $_ if $_ % 2;
}

使用map

my @odd = map { $_ % 2 ? $_ : () } @array;

甚至是array slice使用grep..

my @odd = @array[grep { ! ($_ % 2) } 0 .. $#array];
于 2013-08-11T18:10:48.520 回答
3

的含义$_ & 1上面已经解释过了,但是在这种情况下,我相信如果你写成这样会更易于维护:

my @oddArray = grep { $_ % 2 != 0 } @array;

于 2013-08-12T02:42:32.413 回答
2

逻辑:
如果你在奇数和 1 之间进行 AND 运算(当然是二进制),得到的结果总是 1。

工作原理:
上述代码通过在数组元素和数字 1 之间执行按位与运算来查找奇数。如果运算结果为“真”,则将其插入最终数组 (@subArray)。这里的 $_ 是指在迭代期间访问的原始数组的单个元素。

以下是按位与运算的工作原理。

  1. 假设您要确定 3 是否为奇数(二进制表示 3 -> 0011)。
  2. 根据此代码,您正在执行与 1 的按位与运算,其二进制值为 0001。
  3. AND 操作发生在 0011 和 0001 之间,并且由于它是按位的,因此每个与另一个的相应位进行与运算。
  4. 它是这样发生的,
    3 的二进制:0 0 1 1 1
    的二进制:0 0 0 1
    AND 的结果:0 0 0 1
  5. 如您所见,最终结果为 1,这也是最低位(从右开始的第一位)。因此,表达式的结果为“true”,并且通过操作if $_ & 1;将数字插入到, 中。subArraypush
于 2013-08-12T13:54:16.640 回答
1

为什么不简单呢?

my @subArray = grep {$_ & 1} @array;

以及为什么qw(3 4 5 6 7 8 9)在需要数字时使用初始化数组?

my @array = (3, 4, 5, 6, 7, 8, 9);

好多了。您只是在浪费 CPU 时间和内存,更重要的是会误导您的代码阅读者。这向我指出了更明显的代码。

my @subArray = grep {$_ % 2} @array;

性能差异可以忽略不计,而且发生的事情要明显得多。

于 2013-08-12T05:44:08.560 回答