这是我的代码reverse.pl
#!usr/bin/perl -w
use 5.016;
use strict;
while(my $line=<>)
{
my @array=();
push (@array,$line);
@array=reverse@array;
say @array;
}
名为a.txt
A B C D
E F G H
I J K L
M N O P
Q R S T
我的命令是perl reverse.pl a.txt
为什么它不能实现反向功能? 我想显示结果是:
D C B A
H G F E
等等。
答案 0 :(得分:4)
标量上下文中的反转会反转标量。
列表上下文中的反向反转列表,但不反转列表中的每个标量。
您明确将标量$line
转换为包含一个项目的列表,然后反转项目的顺序。
试试这个:
#!/usr/bin/perl
use 5.016;
use strict;
while (my $line=<>) {
chomp($line);
say scalar reverse $line;
}
如果您有一个数组并想要反转每个元素(但不是元素),请使用map
:
my @array = qw(Alpha Beta Gamma);
@array = map { scalar reverse $_ } @array;
print "@array\n";
如果你想两者兼顾(反转每个元素和元素本身),请执行:
@array = map { scalar reverse $_ } reverse @array;
或:
@array = reverse map { scalar reverse $_ } @array;
答案 1 :(得分:2)
当你说:
push @array, $line;
您正在创建一个等于该行的值的数组。
$array[0] = "A B C D";
当你说:
@array = reverse @array;
您正在撤消该单个成员数组。第一个元素成为最后一个,最后一个元素成为第一个,等等。但是,你只有一个元素,所以没有什么可以反转。
您要做的是使用您的行创建一个数组:
my @array = split /\s+/, $line;
这将创建一个数组,每个字符都是数组的一个独立元素。例如,您的第一行:
$array[0] = "A";
$array[1] = "B";
$array[2] = "C";
$array[3] = "D";
现在,如果您在此阵列上使用reverse
,您将获得:
$array[0] = "D";
$array[1] = "C";
$array[2] = "B";
$array[3] = "A";
以下是该计划:
use strict;
use warnings;
use feature qw(say);
while ( my $line = <> ) {
chomp $line;
my @array = split /\s+/, $line;
say join " ", reverse $line;
}
join
函数接受一个数组,并将每个元素连接成一行 - 从而重建你的行。
顺便说一句,我本可以做到这一点:
@array = reverse @array;
say "@array"; #Quotes are important!
这是因为Perl将自动加入一个包含$"
中任何字符的数组。这是一个Perl变量,用于在将数组放在引号中时连接数组,默认值为单个空格。
就个人而言,我更喜欢say join " ", reverse $line;
。更明显的是发生了什么,并且不依赖于很少使用的变量的值。