perl 将数组转换为列表

lsmd5eda  于 2022-11-15  发布在  Perl
关注(0)|答案(5)|浏览(169)
sub get_list {
    return ("one", "two");
}

sub get_array {
    my @a = ("one", "two");

    # need to convert @a to list
    return @a;
}

my $two = get_list(); # desired, assigns last item in list to scalar 
my $count = get_array(); # evaluates array in scalar context, returning a count

在get_array()方法中,我已经创建了一个数组,但我想将其作为列表返回,这样它就可以根据列表规则而不是数组规则进行赋值。当然,数组通常会以更复杂的方式构建(而不是直接从列表中构建)。
我试过使用map,希望它能返回一个值列表,但结果是一样的,split/join也一样。

return map { $_ } @a;
return split /,/, join(",", @a);

如何将数组转换为值列表?

xt0899hw

xt0899hw1#

函数可以使用wantarray来确定它们所在的上下文,并相应地返回一些内容:

sub get_array {
    my @a = ("one", "two");
    return wantarray ? @a : $a[-1];
}
mcdcgff0

mcdcgff02#

wantarray的答案使意图变得明确,这很好。但是如果你想让一些看起来更像魔术的东西(可以称为“列出数组”)来迷惑和打动人们,一个切片就可以做到:

return @a[0..$#a];
ltqd579y

ltqd579y3#

奇怪的是,答案集中在子例程中的东西上,而不是给你正确的答案。如果你想要列表行为,就做列表操作。Perl很大程度上决定了如何基于你正在做的事情来处理事情,所以要舒服地告诉Perl如何处理数据,而不是依靠技巧来使它工作。
在您的情况下,分配给列表:

my( $item ) = get_list(); 
my( $item ) = get_array();

这两个函数都返回第一项,因为左边只有一个变量,而左边的列表忽略了右边列表中的其余项。
如果您想要第二个项目,但不想要第一个或第三个项目,您可以使用undef做为预留位置:

my( undef, $item ) = get_list();

我很少这样做,因为切片更容易:

my $item = (get_list())[1];

如果你想要最后一个条目,取一个列表切片,从最后一个带负下标的条目开始向后计数:

my $item = (get_list())[-1]; 
my $item = (get_array())[-1];

而且,如果您是创建这些子例程的人,并且您只需要列表中的最后一项,则根本不需要返回列表。只需返回您想要的值即可。您会注意到,Perl对它的许多内置函数(localtimeget*等)都是这样做的。
下面是一些例子:

use v5.10;

my( undef, undef, $mode ) = stat('/etc/hosts');
printf "mode is %o\n", $mode;

say "Hour is ", (localtime)[2];

say "User is " . getpwuid(501); # concatenation, so scalar context
my $name = getpwuid(501); # scalar assignment, so scalar context
say "User is $name";

my $uid = (getpwnam($name))[2];
say "UID is $uid";
jtjikinw

jtjikinw4#

请参阅perlop comma operator
二进制“”,是逗号运算符。在标量上下文中,它计算左参数,将该值丢弃,然后计算右参数并返回该值。这就像C的逗号运算符一样。
并参见perldata list value constructors
在不需要列表值的上下文中,看似列表文字的值只是最后一个元素的值,就像C逗号运算符一样。例如,

@foo = ('cc', '-E', $bar);

将整个列表值赋给array @foo,但

$foo = ('cc', '-E', $bar);

将变量$bar的值赋给标量变量$foo。注意,标量上下文中实际数组的值是数组的长度;
map docs
Map表达式、列表
为LIST的每个元素计算BLOCK或EXPR(在本地将$_设置为每个元素),返回由每个此类计算的结果组成的列表值
太好了!正是你想要的:

my @arr = ('a', 'b', 'c');

my $result = map "-->$_<--", @arr;
say $result; #=>3  ???

嘘,晤:
在标量上下文中,[map]返回这样生成的元素的总数。
因此,在阅读Sean的答案后,您可以推测map()的定义相当于执行以下操作:

return wantarray ? (result1, result2,...,resultN) : N;

split也是一样:
将字符串EXPR拆分为字符串列表,并返回列表上下文中的列表,或标量上下文中的列表大小。

scyqe7ek

scyqe7ek5#

我需要一个变量列表。也许其他人也需要:

my $start = 0;
my $length = 10;
my $database = "foo";
my $chapter = "bar";
my @sql_wheres = ();
push(@sql_wheres, "database LIKE ?") if ($database);
push(@sql_wheres, "chapter LIKE ?") if ($chapter);

# more code here to use DBI and initilize $select

$select->execute( (@wheres), $start, $length );

如果没有圆括号(@wheres),它就不起作用。但是有了圆括号,变量就以列表的形式提供了。

相关问题