2011-02-27 52 views
5

使用在先前的問題地圖,適航詢問如何從數組中刪除該第一5個元素: How do I remove the first five elements of an array?是如何工作的:用三元鉤操作者和()

在幾種建議,friedo提供這樣:

my $cnt = 0; @array = map { ++$cnt < 5 ? () : $_ } @array;

我沒有得到()位。請解釋一下這對我是如何工作的,因爲我無法理解它。

我知道三元鉤操作符是這樣工作的: (如果有的話)? (然後執行此):(否則要這樣做)

例如:$a=2; print ($a==2 ? 3 : 4)#這個打印:3 因爲我們有:($一個== 2 3:4) 這意味着:(如果$ a等於到2)? (然後打印3):(否則打印4)

與friedo代碼

所以,第一$ CNT增加1,那麼我們有:

$cnt < 5 ? () : $_ 這意味着: if $cnt is less than 5 ? then () : otherwise $_

我可以看到如何在$ _位的作品,因爲我有時用地圖是這樣的:

@array = map { $_, "\n" } @array

此副本從@array的元素,則以進入副本$ ,然後添加一個\ n換行,然後將其複製在 $回值@array(和它這樣做與@array所有值所以基本上它添加換行符在@array每個元素)

因此


@array = map { if $cnt is less than 5 then () otherwise $_ } @array

意思是這樣的:
@array = map { if $cnt is less than 5 then () otherwise copy the element back to @array }

如此清晰()是指像「擺脫它」 但我只是不知道它是如何工作。請你能解釋一下嗎?

+0

我加了一個註釋,以friedo的回答,他迫使'map'要像'grep'。最好只使用'grep'。 '我的$ count = 0; my @ new_array = grep {++ $ count> 5} @array;'。既然你的問題是如何工作的,我不會發布作爲答案。只是告訴你這一點,所以當你可以使用更好的技術時,你不會使用複雜的技術。注: 'splice'可能是最好的,因爲它正在使用設計來執行此操作的功能。很多時候,Perl的編寫者對這些函數進行了優化,可能比我們使用其他函數自己構建的函數更快/更好。 – 2011-02-27 19:24:15

+0

另請參閱我的答案使用聲明'狀態',我添加到原始問題 – 2011-02-27 19:53:27

回答

9

map中,數組中的每個項目都被傳遞到代碼塊(在$_中),在那裏它可以轉換爲其他值。換句話說,map轉換列表。

在這種情況下,我們希望丟掉計數($cnt)小於5的值。那麼如何在map塊返回「無」的條件爲真?

我們不能說

my $cnt = 0; @array = map { ++$cnt < 5 ? undef : $_ } @array; 

因爲那樣我們就會有一個數組,看起來落得像

(undef, undef, undef, undef, undef, 6, 7, 8 ...) 

這不是我們想要的。

但是,返回()而不是返回空列表。考慮push @foo, ();@bar = (1, 2, 3, (), 4, 5, 6);在這些情況中的每一種情況下,空集合parens都是一個零項列表,它對相關數組沒有任何影響。

空列表在三元組中很有用,您需要返回列表項或根本不需要返回列表項。這也是有用的,迫使一個表達式列表環境中獲得數:

my $count = () = $str =~ /\d/g; 

在這裏,我們把正則表達式在列表上下文中通過將其分配到一個空列表,給我們的字符串中的數字的計數。然後我們將該空列表分配給$count

map中使用列表的另一個常見示例是將某些內容轉換爲散列。例如,

my %unique = map { $_ => 1 } @duplicates; 

在這裏,每個@duplicates單項得到轉變成看起來像('foo' => 1)雖然因爲沒有括號都參與它不是一個明顯的兩個元素的列表。所有這兩個項目列表然後被構建成一個交替的鍵和值構成哈希的大列表。假設你想做這個散列,但排除一些項目。在這種情況下,我們或者需要返回一個鍵/值,或者什麼也沒有。所以這是使用空單的好機會:

my %filtered_unique = map { some_test($_) ? () : ($_ => 1) } @duplicates; 
+0

我看到所以undef而不是()會增加數組中的元素數。感謝friedo,我從你的答案中學到了很多東西。 – Literat 2011-02-27 18:17:56

1

Apparantly你可以返回一個列表,而不是一個元素,並通過地圖加入這些列表和元素構建的結果。在這種情況下,()只是空列表。要獲得更多信息,請複製粘貼示例,並用(1, 2, 3)替換()

+0

謝謝,它照亮了它的工作原理 – Literat 2011-02-27 18:19:22

2

我知道我在這裏的比賽有點晚,但爲什麼不做簡單的事呢?

我@truncated = @array [5 .. $#數組]

+0

'splice'如何? – 2017-02-24 13:18:00