perl中的触发器运算符

perl中的触发器运算符,perl,loops,Perl,Loops,我有一个要求,我需要在循环中为变量的第一次出现执行一条语句 例如: 给定数组my@rand_numbers=qw(1232) 我知道数组中只有3个值(即在本例中为1、2和3) 我想在每个值的第一次相遇时打印一些东西(或做一些事情)(仅在第一次相遇时打印,并且在对应值的连续相遇时不重复打印) 以下是一种方法 my @rand_numbers = qw(1 2 1 2 3 1 3 2); my $came_across_1=0, $came_across_2=0, $came_across_3=0

我有一个要求,我需要在循环中为变量的第一次出现执行一条语句

例如: 给定数组my
@rand_numbers=qw(1232)
我知道数组中只有3个值(即在本例中为1、2和3)
我想在每个值的第一次相遇时打印一些东西(或做一些事情)(仅在第一次相遇时打印,并且在对应值的连续相遇时不重复打印)

以下是一种方法

my @rand_numbers = qw(1 2 1 2 3 1 3 2); 
my $came_across_1=0, $came_across_2=0, $came_across_3=0;

for my $x(@rand_numbers) { 
    print "First 1\n" and $came_across_1=1 if($x==1 and $came_across_1==0); 
    print "First 2\n" and $came_across_2=1 if($x==2 and $came_across_2==0); 
    print "First 3\n" and $came_across_3=1 if($x==3 and $came_across_3==0); 
    print "Common op for -- $x \n"; 
}
有没有一种方法可以在没有像
$comed\u cover\u x
这样的变量的情况下实现上述结果?[即在触发器操作员的帮助下?]

谢谢,
Ranjith

这可能不适用于您的实际情况,但它适用于您的样本,并可能给您一个想法:

my %seen;
for my $x (@rand_numbers) {
  print "First $x\n" unless $seen{$x}++;
  print "Common op for -- $x\n"
}

只需使用@Chris建议的散列

在这里使用触发器运算符似乎不太实际,因为您仍然需要跟踪所看到的变量:

my %seen;
for (@rand_numbers) {
    print "$_\n" if $_ == 1 && !$seen{$_}++ .. $_ == 1;
    print "$_\n" if $_ == 2 && !$seen{$_}++ .. $_ == 2;
    print "$_\n" if $_ == 3 && !$seen{$_}++ .. $_ == 3;
}

假设您要对遇到的每个不同项执行相同的操作,您可以很容易地将其分解为一个子例程,并首先写入
do_for_($x),除非$seen{$x}++;为所有人做事($x)
Hi Chris,我的主要动机不是使用临时变量[在本例中,您使用了“%seen”散列]。对不起,如果我的问题让人困惑。然而,对于这个场景,您所建议的是最佳方法,但是为了理解perl中可用的一行程序,我想知道我们是否只能使用触发器操作符(或其他一些特殊变量/特殊操作符)来实现它.@Ranjith注意,使用一个哈希表比你的
$comed\u across\u i
变量好上百万倍,也更灵活。@Ranjith-如果你不想看到临时变量,你可以做
{my%seed\u data;sub-seen{u}$seed\u data{$[0]}++:%seed\u data=()}
。在您的循环调用
之前看到
清除散列(以防万一您在别处使用它),然后在循环中将
替换为
除非$seen{$x}++
seen$x
。然后在循环调用
之后,查看以清除它。事实上,你可以(应该?)把这些都放在一个模块中,让不同的操作更清晰一些,但基本原则仍然有效。至于你想使用触发器操作符而不想使用临时变量的顾虑:锤子是用来钉的,螺丝刀是用来钉的。要知道你是否见过某样东西,最好的办法是在你看到它时把它放在某个地方。这是最可读的方法,您将看到这段代码(或类似的代码:
@list=grep{!$seen{$\u}++}@list
在Perl中大量使用。您可能可以使用触发器操作符来实现这一点,但人们抱怨Perl本身不够可读。