我的问题的原始代码(函数提取交叉)使用两个单独的数组$x和$y here我称之为:
my @x = @{ $_[0] }; my @y = @{ $_[1] }; ... return extract_crossing(\@x,\@y);
下面基于answer的新代码采用(x,y)并返回单个数据类型,这里是x拦截点:
use strict; use warnings; use Math::Geometry::Planar qw(SegmentLineIntersection); use Test::Exception; sub x_intercepts { my ($points) = @_; die 'Must pass at least 2 points' unless @$points >= 2; my @intercepts; my @x_axis = ( [0,0],[1,0] ); foreach my $i (0 .. $#$points - 1) { my $intersect = SegmentLineIntersection([@$points[$i,$i+1],@x_axis]); push @intercepts,$intersect if $intersect; } return \@intercepts; }
我试着像这样打电话:
my @x = @{ $_[0] }; my @y = @{ $_[1] }; ... my $masi = x_intercepts(\@x); return $masi;
但是,代码没有意义.
我很困惑将“double数组”传递给x_intercepts()函数.
如何使示例代码更清晰到原始设置?
解决方法
再次 – 它并不完全清楚 – 但似乎您的数据在两个不同的数组中:一个包含所有x值,另一个包含相应的y值.是这样的吗?如果这不正确,请发表评论,我将删除此答案.
如果这是您问题的根源,那么您可以在将数据传递给x_intercepts之前“munge”或转换数据,或者 – 如@ThisSuitIsBlackNot建议的那样 – 您可以重写该函数.下面是将现有数据整合到“@input_list”以传递给x_intercepts的示例.
my @xs = qw/-1 1 3/; my @ys = qw/-1 1 -1 /; my @input_list ; foreach my $i ( 0..$#ys ) { push @input_list,[ $xs[$i],$ys[$i] ] ; } my $intercept_list = x_intercepts(\@input_list) ; say join ",",@$_ for @$intercept_list ;
将上面的行添加到脚本中会产生:
输出:
0,0 2,0
你必须非常小心地做这种事情,并使用测试来确保以预期的方式传递正确转换的数据是一个好主意.
我认为更普遍的困难是,在熟悉perl之前,有时候很容易看出子程序期望的值是什么,它们在传入之后最终会出现,以及如何访问它们.
对perl数据结构的扎实掌握可以帮助解决这个问题 – 例如我认为你所谓的“双数组”或“双元素”是“array of arrays”.有很多方法可以让你更容易看到默认参数传递给a子程序(在@_中)正在进行(请注意@ThisSuitIsBlackNot如何将它们传递给一个命名良好的数组引用:“($points)”).大量重新阅读perldocperbsub
可以帮助事情看起来更加明显.
References是理解perl子例程的关键,因为要将数组或哈希传递给子路由,需要通过引用来实现.如果传递的参数x_intercepts是两个匿名数组列表的列表,那么当它被分配给($points)时,@ $points-> [0] @ $points-> [1]将是包含这些列表的数组.
我希望这有帮助,而且不是太基本(或不正确).如果@ThisSuitIsBlackNot找不到提供答案的时间,你应该接受它:已经提供了一些非常有用的例子.