优化perl代码
我必须写检查数组ref是否有3个以上的参数。如果该值来自一个数组,那么我已经为此编写了一个foreach循环,然后将其切掉,并在连接管道后分配给一个新变量 代码 我想为这种工作编写一个函数,这样就不会重复相同的代码。请帮帮我;如何在Perl中实现这一点?您可以编写:优化perl代码,perl,Perl,我必须写检查数组ref是否有3个以上的参数。如果该值来自一个数组,那么我已经为此编写了一个foreach循环,然后将其切掉,并在连接管道后分配给一个新变量 代码 我想为这种工作编写一个函数,这样就不会重复相同的代码。请帮帮我;如何在Perl中实现这一点?您可以编写: sub convert_to_name ($$) { # ($value, $fallback_name) my ($value, $fallback_name) = @_; if (defined $value)
sub convert_to_name ($$) { # ($value, $fallback_name)
my ($value, $fallback_name) = @_;
if (defined $value) {
if (ref($value) eq 'ARRAY') {
return join '|', @$value;
} else {
return "$value";
}
} else {
return $fallback_name;
}
}
$args->{'hotel_name'} = convert_to_name $args->{'hotel'}, $hotel;
$args->{'country_name'} = convert_to_name $args->{'country'}, $country;
$args->{'city_name'} = convert_to_name $args->{'city'}, $city;
你可以写:
sub convert_to_name ($$) { # ($value, $fallback_name)
my ($value, $fallback_name) = @_;
if (defined $value) {
if (ref($value) eq 'ARRAY') {
return join '|', @$value;
} else {
return "$value";
}
} else {
return $fallback_name;
}
}
$args->{'hotel_name'} = convert_to_name $args->{'hotel'}, $hotel;
$args->{'country_name'} = convert_to_name $args->{'country'}, $country;
$args->{'city_name'} = convert_to_name $args->{'city'}, $city;
代码中似乎存在一些潜在的错误,最大的错误集中在在较低范围内重用变量名 然而,您当然可以在代码中添加一个迭代循环,这样就不需要3个几乎相同的部分。下面通过创建一个中间散列数据结构将字段名与值关联起来来实现这一点 注意:我还通过反转第一个if语句的逻辑if简化了代码,这样所有if都可以处于同一级别。此外,使用
join
而不是滚动您自己的此类功能也是有意义的
my %hash = (
hotel => $hotel,
country => $country_name,
city => $city,
);
while ( my ( $field, $value ) = each %hash ) {
if ( !defined $args->{$field} ) {
$args->{"${field}_name"} = $value;
} elsif ( ref( $args->{$field} ) eq "ARRAY" ) {
$args->{"${field}_name"} = join '|', @{ $args->{$field} };
} else {
$args->{"${field}_name"} = $args->{$field};
}
}
此外,如果您对条件运算符感到满意,则可以进一步减少。然而,有些人会认为这太混乱:
while ( my ( $field, $value ) = each %hash ) {
$args->{"${field}_name"} = !defined $args->{$field}
? $value
: ref( $args->{$field} ) eq "ARRAY"
? join( '|', @{ $args->{$field} } )
: $args->{$field};
}
代码中似乎存在一些潜在的错误,最大的错误集中在在较低范围内重用变量名 然而,您当然可以在代码中添加一个迭代循环,这样就不需要3个几乎相同的部分。下面通过创建一个中间散列数据结构将字段名与值关联起来来实现这一点 注意:我还通过反转第一个if语句的逻辑if简化了代码,这样所有if都可以处于同一级别。此外,使用
join
而不是滚动您自己的此类功能也是有意义的
my %hash = (
hotel => $hotel,
country => $country_name,
city => $city,
);
while ( my ( $field, $value ) = each %hash ) {
if ( !defined $args->{$field} ) {
$args->{"${field}_name"} = $value;
} elsif ( ref( $args->{$field} ) eq "ARRAY" ) {
$args->{"${field}_name"} = join '|', @{ $args->{$field} };
} else {
$args->{"${field}_name"} = $args->{$field};
}
}
此外,如果您对条件运算符感到满意,则可以进一步减少。然而,有些人会认为这太混乱:
while ( my ( $field, $value ) = each %hash ) {
$args->{"${field}_name"} = !defined $args->{$field}
? $value
: ref( $args->{$field} ) eq "ARRAY"
? join( '|', @{ $args->{$field} } )
: $args->{$field};
}
将lambda映射到属性数组上?我不知道有没有其他简单的方法可以优化代码并删除重复的内容而不是
chop
(现代chomp
的前身)简单地从参数中删除最后一个字符,因此如果您刚刚添加了一个尾管,chop
删除它。那么,您想优化还是删除重复?这些目标互不相关,可能相互冲突。你接受的答案比你的代码稍慢。将lambda映射到属性数组上?我不知道有没有其他简单的方法可以优化代码并删除重复的内容?不要将chop(现代的chomp的前身)简单地从参数中删除最后一个字符,所以,如果你刚刚添加了一个拖尾管,chop
会删除它。那么,你想优化还是删除重复?这些目标互不相关,可能相互冲突。您接受的答案比您的代码稍慢。convert_to_name($args->{'hotel'})/$hotel
如果5.10可用会更好,因为它避免在不需要时生成默认值,并且避免复制它。@ikegami:FYI,我回滚了您的编辑,因为字符串化是有意的。Bug:返回“$value”
不必要地复制了$value
。它还可能损坏各种数据。它应该是返回$value代码>/Nit:$fallback\u name
对于默认值来说是一个相当糟糕的名称<代码>$default
更合适。//Nit:convert\u to\u name
是一个相当糟糕的名称,因为sub没有转换为名称。//妮特:关于ref
的参数,而不是关于定义的的参数,这些参数是什么?@ikegami:我写这个答案是基于我对OP试图做什么的理解。你的大多数“缺点”是你认为OP试图做一些不同的事情,其余的只是你喜欢一种不同于我喜欢的编码风格。欢迎您发布自己喜欢的答案。convert_to_name($args->{'hotel'})/$hotel
如果5.10可用会更好,因为它避免在不需要时生成默认值,并避免复制它。@ikegami:FYI,我回滚了您的编辑,因为字符串化是有意的。Bug:return“$value”
不必要地复制了$value
。它还可能损坏各种数据。它应该是返回$value代码>/Nit:$fallback\u name
对于默认值来说是一个相当糟糕的名称<代码>$default
更合适。//Nit:convert\u to\u name
是一个相当糟糕的名称,因为sub没有转换为名称。//妮特:关于ref
的参数,而不是关于定义的的参数,这些参数是什么?@ikegami:我写这个答案是基于我对OP试图做什么的理解。你的大多数“缺点”是你认为OP试图做一些不同的事情,其余的只是你喜欢一种不同于我喜欢的编码风格。欢迎你发表你自己的答案,这是你喜欢的。