Pet*_*and 2 arrays perl reference
我有这个例子:
my $numbers = [ 1, 2, 3, 4, 5, 6 ];
my $newarray = [ reverse @$numbers ];
Run Code Online (Sandbox Code Playgroud)
此示例包含一些合成代码,以使$numbersarrayref适合该reverse函数.我想删除该代码并执行更多类似的操作:
my $newarray = reverse $numbers;
Run Code Online (Sandbox Code Playgroud)
我知道这不起作用,它返回:
)8936f22x0(YARRA
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法在不更改第一行的情况下在Perl中反转arrayref ?
更新:
my $mails = [ reverse @{$mail_api->GetLogSendMail({ customer_id => $id })} ];
Run Code Online (Sandbox Code Playgroud)
我们的想法是让上面的代码更好.
如果您可以使用array而不是arrayref,那么试试这个:
my @newarray = reverse @$numbers;
Run Code Online (Sandbox Code Playgroud)
代码my $newarray = reverse $numbers无效,因为reverse在标量上下文中调用,这使得它以相反的顺序返回字符串.来自reverse手册:
在标量上下文中,连接LIST的元素并返回一个字符串值,其中所有字符的顺序相反.
如果在上面的某处声明$ newarray变量,可以按以下方式编写它:
## declare $newarray somewhere else
@$newarray = reverse @$numbers;
Run Code Online (Sandbox Code Playgroud)
更新
可能是你想创建自己的功能:
sub reverse_by_ref {
return [ reverse @{$_[0]} ];
}
Run Code Online (Sandbox Code Playgroud)
我认为这里真正的基本问题是你存储$numbers为array-ref并尝试将它们作为数组进行操作.这可能是常见的,但不正确.人们这样做是为了使数组始终保持参考形式,但正确的方法是使用原生结构而不是对它的引用.在参考形式scalar中reverse,pop/push/shift/unshift和所有其他人将需要明确的参与来操作阵列.这对于允许引用数组的所有语言都是通用的 - 查看C的字符指针与字符数组以及sizeof()运算符之类的内容.我们在这里真正做的是利用perl非常方便的匿名数组语法来弥补自己的不利.
这不是一个真正的问题,但是取消引用的微小开销和差异的几乎不可避免的视觉元素.现在继续到/右/回答.有一个现代化的解决方案,它与之相伴autobox.Autobox提供包含类似对象语法的所有类型引用.
use autobox;
my $arr = [ 1 .. 10 ];
$arr->reverse;
Run Code Online (Sandbox Code Playgroud)
只是跟进,真正的原因,为什么我们有匿名数组的语法是创建与深层结构,避免将阵列(需要将它们推到堆栈),远远超过创造的东西,应该是数组作为阵列的裁判.
$foo( [1..100] ) 比...快得多 $foo( 1..100 )$arr[1] = [1,2,3] 比方便更方便 @temp = 1,2,3; $arr[1] = \@temp你有几个选择.
不要试图在一条线上塞满所有东西:
my $mails = [ reverse @{$mail_api->GetLogSendMail({ customer_id => $id })} ];
Run Code Online (Sandbox Code Playgroud)
变为:
my $mails = $mail_api->GetLogSendMail({ customer_id => $id });
@$mails = reverse @$mails;
Run Code Online (Sandbox Code Playgroud)
如果GetLogSendMail愚蠢到返回对你不应该搞乱的数组的引用,那么你将不得不稍微修改它以创建一个新数组:
my $inviolate_mails = $mail_api->GetLogSendMail({ customer_id => $id });
my $mails; @$mails = reverse @$inviolate_mails;
Run Code Online (Sandbox Code Playgroud)
为了将所有内容保持在一行,请使用Ivan Nevostruev建议的子程序:
sub reverse_ref \@ {
return [ reverse @{$_[0]} ];
}
my $mails = reverse_ref $mail_api->GetLogSendMail({ customer_id => $id });
Run Code Online (Sandbox Code Playgroud)
如果您需要在数组引用上执行大量列表操作,请考虑创建一个库:
package ArrayRef::Util;
# boiler plate skipped.
sub reverse_ref \@ {
return [ reverse @{$_[0]} ];
}
sub push_ref \@\@ {
push @{$_[0]}, @{$_[1]};
}
# and so on
Run Code Online (Sandbox Code Playgroud)
最后,Evan Carroll的autobox建议也有帮助:
use autobox;
my $mails = [ $mail_api->GetLogSendMail({ customer_id => $id })->reverse ];
Run Code Online (Sandbox Code Playgroud)
请参阅我应该在Perl中使用autobox吗?有关autobox的更多信息.