【问题标题】:Flip flop operator in perlperl 中的触发器运算符
【发布时间】:2010-11-22 10:25:52
【问题描述】:

我有一个要求,我需要在循环内执行一个语句,以便第一次出现变量。

例如: 给定数组我的@rand_numbers = qw(1 2 1 2 3 1 3 2);
我知道数组中只有 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"; 
}

有没有办法在没有像 $came_across_x 这样的变量的情况下实现上述结果? [IE。在触发器运算符的帮助下?]

谢谢, 兰吉特

【问题讨论】:

    标签: perl loops


    【解决方案1】:

    这可能不适用于您的实际情况,但它适用于您的示例,并且可能会给您一个想法:

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

    【讨论】:

    • 假设遇到的每一个不同的项目你想做的事情都是一样的,你可以很容易地把它分解成一个子程序,写do_for_first($x) unless $seen{$x}++; do_for_all($x);
    • 嗨 Chris,我的主要动机是不使用临时变量 [就像在这种情况下你使用了 '%seen' 哈希值]。对不起,如果我的问题令人困惑。但是,对于这种情况,您建议的是最佳方法,但是要了解 perl 中可用的单行代码,我想知道我们是否只能使用触发器运算符(或其他一些特殊的变量/特殊运算符)来做到这一点。跨度>
    • @Ranjith 请注意,与您的 $came_across_i 变量相比,使用单个哈希表要好得多,也更灵活。
    • @Ranjith - 如果您不想看到临时变量,您可以使用{ my %seen_data; sub seen { @_ ? $seen_data{$_[0]}++ : %seen_data = () } }。在你的循环调用seen; 清除哈希之前(以防你在其他地方使用它)然后在循环中用seen $x 替换unless $seen{$x}++。然后在循环调用seen; 之后再次清除它。实际上你可以(应该?)把这一切都放在一个模块中,让不同的操作更清晰一些,但基本原则仍然存在。
    • 至于您对想要使用触发器运算符而不想要使用临时变量的担忧:锤子用于钉子,螺丝刀用于螺钉。知道您是否看过某物的最好方法是在您看到某物时将其存放在某个地方。这是执行此操作的最易读的方法,您会看到此代码(或类似的代码:@list = grep { !$seen{$_}++ } @list 创建唯一值列表)在 Perl 中被大量使用。您可能可以使用触发器运算符来做到这一点,但人们抱怨 Perl 本身就不够可读。
    【解决方案2】:

    按照@Chris 的建议,只需使用散列即可。

    在这里使用触发器运算符似乎不切实际,因为无论如何您都需要跟踪看到的变量:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-10
      • 2017-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-07
      • 1970-01-01
      相关资源
      最近更新 更多