Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何在不必重复代码的情况下执行两个不同的Foreach循环_Perl_Foreach_Code Duplication - Fatal编程技术网

Perl 如何在不必重复代码的情况下执行两个不同的Foreach循环

Perl 如何在不必重复代码的情况下执行两个不同的Foreach循环,perl,foreach,code-duplication,Perl,Foreach,Code Duplication,我有一个散列数组和一个普通数组,这取决于环境(即用户在程序运行时选择的选项),其中只定义一个 演示问题的示例代码: my %hashofarrays; my @array; #... #Some code between here where either %hashofarrays or @array gets defined #... if (defined @array) { foreach my $var1 (@array) { print "va

我有一个散列数组和一个普通数组,这取决于环境(即用户在程序运行时选择的选项),其中只定义一个

演示问题的示例代码:

my %hashofarrays;
my @array;

#...
#Some code between here where either %hashofarrays or @array gets defined
#...

if (defined @array) {

    foreach my $var1 (@array) {
        print "var1 is: $var1\n";
        call_subroutine($var1);
        print "Something else is printed";
        call_anothersubroutine($var1);
        call_differentsubroutine($var1);
    }

} 

if (defined %hashofarrays) {

    foreach my $key (keys %hashofarrays) {
        print "the key is: $key\n";
        foreach my $var1 (@{$hashofarrays{$key}}) {
            call_subroutine($var1);
            print "Something else is printed";
            call_anothersubroutine($var1);
            call_differentsubroutine($var1);
        }
    }
}
   
正如您在上面的代码中所看到的,根据是否定义了
@array
或是否定义了
%hashofarray
,它将运行相应的
if
语句

问题:

my %hashofarrays;
my @array;

#...
#Some code between here where either %hashofarrays or @array gets defined
#...

if (defined @array) {

    foreach my $var1 (@array) {
        print "var1 is: $var1\n";
        call_subroutine($var1);
        print "Something else is printed";
        call_anothersubroutine($var1);
        call_differentsubroutine($var1);
    }

} 

if (defined %hashofarrays) {

    foreach my $key (keys %hashofarrays) {
        print "the key is: $key\n";
        foreach my $var1 (@{$hashofarrays{$key}}) {
            call_subroutine($var1);
            print "Something else is printed";
            call_anothersubroutine($var1);
            call_differentsubroutine($var1);
        }
    }
}
   
但问题是,以下代码行在两个
if
语句中重复:

    call_subroutine($var1);
    print "Something else is printed";
    call_anothersubroutine($var1);
    call_differentsubroutine($var1);
显然,如果这些
foreach
循环包含大量代码,这将意味着大量代码将被复制

当涉及到
foreach
循环时,是否有任何方法/可以避免这种代码重复的最佳方法是什么

实际上,是否有一种方法可以执行以下操作:(我很清楚此代码不起作用,但解释了我试图实现的目标)


我可能忽略了一些显而易见的事情,但看不到一种合乎逻辑的方法来做到这一点?

首先,
defined@array
defined%hashofarrays
是错误的。它们总是被定义的。您希望
if(@array)
if(key%hashofarrays)
测试它们是否包含元素。您甚至应该得到一个警告
defined(@array)已弃用

您需要的是另一个子例程

sub loop_body {  # just use some better name!
  my ($var) = @_;
  call_subroutine($var);
  print "Something else is printed";
  call_anothersubroutine($var);
  call_differentsubroutine($var);
}
然后:

您还可以使用回调使解决方案更加灵活:

 sub loop_with_cb {
   my $cb = shift;
   for my $var (@_) {
     if ($cb) {
       local $_ = $var; # make $_ visible to the callback
       $cb->($var);
     }
     call_subroutine($var);
     print "Something else is printed";
     call_anothersubroutine($var);
     call_differentsubroutine($var);
   }
 }
然后:


首先,
defined@array
defined%hashofarrays
是错误的。它们总是被定义的。您希望
if(@array)
if(key%hashofarrays)
测试它们是否包含元素。您甚至应该得到一个警告
defined(@array)已弃用

您需要的是另一个子例程

sub loop_body {  # just use some better name!
  my ($var) = @_;
  call_subroutine($var);
  print "Something else is printed";
  call_anothersubroutine($var);
  call_differentsubroutine($var);
}
然后:

您还可以使用回调使解决方案更加灵活:

 sub loop_with_cb {
   my $cb = shift;
   for my $var (@_) {
     if ($cb) {
       local $_ = $var; # make $_ visible to the callback
       $cb->($var);
     }
     call_subroutine($var);
     print "Something else is printed";
     call_anothersubroutine($var);
     call_differentsubroutine($var);
   }
 }
然后:


使用另一个函数可能会有所帮助

if (@array) {
    my_func(\@array);
} 
if (%hashofarrays) {
    foreach my $key (keys %hashofarrays) {
        print "the key is: $key\n";
        my_func($hashofarrays{$key});
    }
}

sub my_func {
    my ($arr) = @_;

    foreach my $var1 (@$arr) {
        call_subroutine($var1);
        print "Something else is printed";
        call_anothersubroutine($var1);
        call_differentsubroutine($var1);
    }

}

使用另一个函数可能会有所帮助

if (@array) {
    my_func(\@array);
} 
if (%hashofarrays) {
    foreach my $key (keys %hashofarrays) {
        print "the key is: $key\n";
        my_func($hashofarrays{$key});
    }
}

sub my_func {
    my ($arr) = @_;

    foreach my $var1 (@$arr) {
        call_subroutine($var1);
        print "Something else is printed";
        call_anothersubroutine($var1);
        call_differentsubroutine($var1);
    }

}
正如阿蒙所说,
if(defined@array)
是错误的,但我甚至不会为
if(@array)
而烦恼,除非你有一个
else
。您可以直接转到(@array)
,如果
@array
为空,它将迭代零次,基本上就像
if
一样跳过循环

这样看来,您希望对
@array
中的每个元素和
%数组散列中的每个键执行相同的操作,对吗?您甚至不需要
子系统

for (@array, map { @$_ } values %hashofarrays) {
  my $var1 = $_;
  print "var is: $var1\n";
  call_subroutine($var1);
  print "Something else is printed";
  call_anothersubroutine($var1);
  call_differentsubroutine($var1);
}
编辑:修改代码,以循环遍历
%hashofarrays
中数组的内容,而不是其键。这仍然与初始问题中的代码不完全匹配,因为它在hoa上循环时打印
$var1
,而不是打印哈希键,但看起来OP的实际用例很有可能除了索引到哈希之外不使用任何键,在这种情况下,它实际上并不需要(因为我们可以使用
值%hoa

正如阿蒙所说,
if(defined@array)
是错误的,但我甚至不会为
if(@array)
而烦恼,除非你有一个
else
。你可以直接转到
for(@array)
并且,如果
@array
为空,它将迭代零次,本质上就像
if
一样跳过循环

这样看来,您希望对
@array
中的每个元素和
%数组散列中的每个键执行相同的操作,对吧?您甚至不需要

for (@array, map { @$_ } values %hashofarrays) {
  my $var1 = $_;
  print "var is: $var1\n";
  call_subroutine($var1);
  print "Something else is printed";
  call_anothersubroutine($var1);
  call_differentsubroutine($var1);
}

编辑:修改代码,以循环
%hashofarrays
中数组的内容,而不是其键。这仍然与初始问题中的代码不完全匹配,因为它在循环hoa时打印
$var1
,而不是打印哈希键,但看起来很有可能's的实际用例除了索引到散列中之外不使用键,在这种情况下,无论如何都不需要它(因为我们可以使用
值%hoa
).

这个答案可能会有帮助:在数组和哈希上使用
定义的
是不推荐的。@perl用户是不推荐的。这个答案可能会有帮助:在数组和哈希上使用
定义的
是不推荐的。@perl用户是不推荐的。@
而不是
local$\u=$var;
@mpapec我考虑过这一点,但我认为尽可能使用显式的词汇循环变量是很重要的。显式的
local
也是一种强有力的表达方式,“我希望让我调用的subs能够看到这一点。”考虑到OP对Perl的了解,应该避免隐式行为。我不久前对手动本地化
$\uuu
感到愤怒,但不记得为什么应该避免隐式行为。我将尝试查找那篇文章。@mpapec我对这样一篇文章感兴趣。但你确定你没有将其与词法
$\u
混淆吗?现在
my$\
与5.10中的其他错误一起被劝阻。也许(@{my$var=$\}
而不是
local$\=$var;
@mpapec我考虑过这一点,但我认为尽可能使用显式的词汇循环变量是很重要的。显式的
local
也是一种强有力的表达方式“我希望让我调用的sub可以看到这一点。”考虑到OP对Perl的了解,应该避免隐式行为。我不久前对
$\uuuu
的手动本地化很感兴趣,但不记得为什么应该避免。我将试着找到那篇文章。@mppec我对这篇文章很感兴趣。Bu