簡介
List::Util 是一個實用的對列表進(jìn)行操作的功能函數(shù)工具集合侵浸。
use List::Util qw(
reduce any all none notall first
max maxstr min minstr product sum sum0
pairs unpairs pairkeys pairvalues pairfirst pairgrep pairmap
shuffle uniq uniqnum uniqstr
);
在List::Util 中包含的這些函數(shù),默認(rèn)情況下是不會被導(dǎo)入的。除非在use List::Util時明確指定。
從列表到單值的映射函數(shù)
以下介紹的所有函數(shù)都會處理一個列表并按要求返回一個單一的值。
reduce
$result = reduce { BLOCK } @list
遍歷列表妙啃,反復(fù)調(diào)用BLOCK,第一次調(diào)用BLOCK時把列表的前兩個元素分別設(shè)置為$a,$b俊戳;以后每次調(diào)用以上次次調(diào)用BLOCK的返回值為$a揖赴,以列表中的下一個元素為$b。直到列表中的所有元素處理完后抑胎,返回BLOCK的返回值燥滑。如果列表為空肾扰,則返回undef业稼。如果列表中只有一個元素,那么該元素被返回穴吹,BLOCK不被執(zhí)行。
以下代碼段演示了如何使用 reduce 函數(shù)實現(xiàn)本模塊中其他“從列表到單值映射的函數(shù)”羽历。(他們并不是這樣實現(xiàn)的焊虏,而是在單個C函數(shù)中以更有效的方式實現(xiàn)。)
$foo = reduce { defined($a) ? $a :$code->(local $_ = $b)? $b :undef } undef, @list # first
$foo = reduce { $a > $b ? $a : $b } 1..10 # max
$foo = reduce { $a gt $b ? $a : $b } 'A'..'Z' # maxstr
$foo = reduce { $a < $b ? $a : $b } 1..10 # min
$foo = reduce { $a lt $b ? $a : $b } 'aa'..'zz' # minstr
$foo = reduce { $a + $b } 1 .. 10 # sum
$foo = reduce { $a . $b } @bar # concat
$foo = reduce { $a || $code->(local $_ = $b) } 0, @bar # any
$foo = reduce { $a && $code->(local $_ = $b) } 1, @bar # all
$foo = reduce { $a && !$code->(local $_ = $b) } 1, @bar # none
$foo = reduce { $a || !$code->(local $_ = $b) } 0, @bar # notall
# Note that these implementations do not fully short-circuit
如果您的算法需要讓reduce返回一個類型的值秕磷,那么請確保始終將該類型的值作為BLOCK的第一個參數(shù)傳遞诵闭,以免返回undef。
$foo = reduce { $a + $b } 0, @values; # sum with 0 identity value
any
my $bool = any { BLOCK } @list;
如果列表中的元素澎嚣,有任何一個能使BLOCK返回true疏尿,則返回true;只有當(dāng)列表中的所有元素都使用BLOCK返回false時才返回false易桃。
if( any { length > 10 } @strings ) {
# at least one string has more than 10 characters
}
all
my $bool = all { BLOCK } @list;
只有列表中的所有元素都使BLOCK返回true時褥琐,才返回true。如果列表中有任何一個元素使得BLOCK返回false晤郑,則返回false敌呈。
none & notall
my $bool = none { BLOCK } @list;
my $bool = notall { BLOCK } @list;
對于none函數(shù),只有列表中的所有函數(shù)都使BLOCK返回false時才返回true造寝;如果列表中有一個元素使得BLOCK返回true磕洪,則返回false。
對于notall函數(shù)诫龙,如果列表中有一個元素使得BLOCK返回false則返回true析显。只有列表中所有元素都使得BLOCK返回true時才返回false。
first
my $val = first { BLOCK } @list;
返回列表中第一個能夠使得BLOCK返回true的元素签赃。
$foo = first { defined($_) } @list # first defined value in @list
$foo = first { $_ > $value } @list # first value in @list which
# is greater than $value
max
my $num = max @list;
返回列表中數(shù)值最大的元素谷异。如果列表為空則返回undef。
$foo = max 1..10 # 10
$foo = max 3,9,12 # 12
$foo = max @bar, @baz # whatever
maxstr
my $str = maxstr @list;
類似于 max 函數(shù)姊舵,把列表中的所有值視為字符串晰绎,返回列表中以字符串方式比較得到的最大的元素。
$foo = maxstr 'A'..'Z' # 'Z'
$foo = maxstr "hello","world" # "world"
$foo = maxstr @bar, @baz # whatever
min
my $num = min @list;
返回列表中的數(shù)值最小的元素括丁。如果列表為空則返回undef。
$foo = min 1..10 # 1
$foo = min 3,9,12 # 3
$foo = min @bar, @baz # whatever
minstr
my $str = minstr @list;
類似于 min 函數(shù)伶选,把列表中的所有值視為字符串史飞,返回列表中以字符串方式比較得到的最小的元素。
$foo = minstr 'A'..'Z' # 'A'
$foo = minstr "hello","world" # "hello"
$foo = minstr @bar, @baz # whatever
product
my $num = product @list;
返回列表中所有元素數(shù)值乘積仰税。如果@list為空則返回1构资。
$foo = product 1..10 # 3628800
$foo = product 3,9,12 # 324
sum
my $num_or_undef = sum @list;
返回列表中所有元素的數(shù)值和,如果列表為空則返回undef陨簇。
$foo = sum 1..10 # 55
$foo = sum 3,9,12 # 24
$foo = sum @bar, @baz # whatever
sum0
my $num = sum0 @list;
在功能上與 sum 相同吐绵,唯一的區(qū)別是當(dāng)參數(shù)是一個空列表時,返回的不是nudef而是 0.
從列表到鍵值對的映射函數(shù)
pairs
my @pairs = pairs @kvlist;
參數(shù)為一個偶數(shù)個元素的列表@kvlist,返回一個數(shù)組引用的列表己单,每個數(shù)組引用中包含@kvlist兩個元素唉窃。此函數(shù)與下面的代碼返回的結(jié)果是一樣的。
@pairs = pairmap { [ $a, $b ] } @kvlist
在for循環(huán)中使用些方法的例子如下:
foreach my $pair ( pairs @kvlist ) {
my ( $key, $value ) = @$pair;
...
}
自 1.39 版本以后纹笼,這些ARRAY引用都是被祝福過的對象纹份,可以使用類似下面的方法獲取key和value。
foreach my $pair ( pairs @kvlist ) {
my $key = $pair->key;
my $value = $pair->value;
...
}
unpairs
my @kvlist = unpairs @pairs
這個函數(shù)是pairs的逆函數(shù)廷痘,此函數(shù)將以ARRAY引用(每個ARRAY引用中只有兩個元素)為元素的列表處理成一個平坦化的列表蔓涧。在意思上相當(dāng)于以下代碼的功能:
my @kvlist = map { @{$_}[0,1] } @pairs
對于參數(shù)列表中的每個ARRAY引用它都會提取兩個值放到返回列表中。如果作為元素的ARRAY引用中有多余兩個的元素笋额,則后面的元素會被忽略元暴;如果少于兩個元素,則會使用undef代替兄猩。
下面的代碼是一種應(yīng)用場景茉盏,用于對鍵值對進(jìn)行排序。
@kvlist = unpairs sort { $a->key cmp $b->key } pairs @kvlist
pairkeys
my @keys = pairkeys @kvlist;
返回給定列表所映射到的每個“鍵值對”中鍵的列表厦滤。與下面的代碼是等效的:
@keys = pairmap { $a } @kvlist
pairvalues
my @values = pairvalues @kvlist;
返回給定列表所映射到的每個“鍵值對”中值的列表援岩。與下面的代碼是等效的:
@values = pairmap { $b } @kvlist
pairgrep
my @kvlist = pairgrep { BLOCK } @kvlist;
my $count = pairgrep { BLOCK } @kvlist;
與perl的grep關(guān)鍵字類似,但將給定列表解釋為“鍵值對”的列表掏导。然后在標(biāo)量上下文件中調(diào)用BLOCK享怀,參數(shù)$a和$b是“鍵值對”列表中一個元素的“鍵”和“值”,也就是@kvlist列表中連續(xù)的兩個元素趟咆。返回一個列表添瓷,列表中的元素是所有使得BLOCK返回true的“鍵值對”(不是ARRAY的引用哦,是以兩個值作為兩個元素存在于列表中)值纱。在標(biāo)量上下文件中返回的是結(jié)果列表中的“鍵值對”的數(shù)量鳞贷,是元素數(shù)量的一半。
@subset = pairgrep { $a =~ m/^[[:upper:]]+$/ } @kvlist
pairfirst
my ( $key, $val ) = pairfirst { BLOCK } @kvlist;
my $found = pairfirst { BLOCK } @kvlist;
類似于 first 函數(shù)的功能虐唠,但將給定列表解釋為“鍵值對”的列表搀愧。然后在標(biāo)量上下文件中調(diào)用BLOCK,參數(shù)$a和$b是“鍵值對”列表中一個元素的“鍵”和“值”疆偿,也就是@kvlist列表中連續(xù)的兩個元素咱筛。返回一個僅包含兩個元素的列表,這兩個元素就是第一個使得BLOCK返回true的“鍵值對”的鍵和值杆故。如果所有“鍵值對”都無法使用得BLOCK返回true迅箩,則返回一個空列表。在標(biāo)量上下文件中返回一個簡單的布爾值处铛,而不是“鍵值對”或找到的值饲趋。
( $key, $value ) = pairfirst { $a =~ m/^[[:upper:]]+$/ } @kvlist
pairmap
my @list = pairmap { BLOCK } @kvlist;
my $count = pairmap { BLOCK } @kvlist;
與perl的grep關(guān)鍵字類似拐揭,但將給定列表解釋為“鍵值對”的列表。然后在標(biāo)量上下文件中調(diào)用BLOCK奕塑,參數(shù)$a和$b是“鍵值對”列表中一個元素的“鍵”和“值”堂污,也就是@kvlist列表中連續(xù)的兩個元素。返回一個列表爵川,列表中的元素是每次調(diào)用BLOCK得到的返回值組成的列表敷鸦。在標(biāo)量上下文件中返回的是結(jié)果列表的長度。
其他函數(shù)
shuffle
my @values = shuffle @values;
以隨機的順序?qū)斎氲脑剡M(jìn)行排列并返回寝贡。
@cards = shuffle 0..51 # 0..51 in a random order
uniq
my @subset = uniq @values
返回一個不包含任何重復(fù)元素的列表扒披。對原列表進(jìn)行處理,確保在前面已經(jīng)出現(xiàn)的元素不會在后面的處理中被加入到返回的列表中圃泡。
my $count = uniq @values
在標(biāo)題上下文件返回結(jié)果列表的長度碟案。
注:此函數(shù)認(rèn)為 undef與空字符串是不同的,并且不會產(chǎn)生警告颇蜡。它在返回的列表中按原樣保留价说。后續(xù)undef值仍然被認(rèn)為與第一個值相同,并將被刪除风秤。
uniqnum
my @subset = uniqnum @values
把參數(shù)列表中的所有元素都當(dāng)成數(shù)字處理鳖目,返回一個不包含任何重復(fù)元素的列表。對原列表進(jìn)行處理缤弦,確保在前面已經(jīng)出現(xiàn)的元素不會在后面的處理中被加入到返回的列表中领迈。
my $count = uniqnum @values
在標(biāo)題上下文件返回結(jié)果列表的長度。
注:此函數(shù)把undef空成數(shù)字0對待碍沐。
uniqstr
my @subset = uniqstr @values
把參數(shù)列表中的所有元素都當(dāng)成字符串處理狸捅,返回一個不包含任何重復(fù)元素的列表。對原列表進(jìn)行處理累提,確保在前面已經(jīng)出現(xiàn)的元素不會在后面的處理中被加入到返回的列表中尘喝。
my $count = uniqstr @values
在標(biāo)題上下文件返回結(jié)果列表的長度。
注:此函數(shù)把undef空成空字符串對待斋陪。