2009-11-05 99 views
2

我只是想縮短線路的指派HTML ::元素 - > as_trimmed_text從HTML ::元素的數組到一些變量的代碼 - 非常標準的東西,如:我可以將Perl映射與數組切片一起使用嗎?

my ($var1, var2) = ($columns[1]->as_trimmed_text, $columns[2]->as_trimmed_text); 

..except那還有幾列,所以它會繼續多行。我有一個好主意,我可以用地圖來代替,但我並沒有太多的運氣。我試過的變化上

map { $_->as_trimmed_text } @columns[1, 3, 5, 7, 9] 

,但我不斷收到無法調用「as_trimmed_text」沒有包裝或對象引用。

是否有可能做我正在嘗試,或者我應該堅持我現在擁有的?

TIA

編輯:列 - >列

+2

目前看起來您正在使用不同的變量:第一個示例爲「@ column」,第二個爲「@ columns」。但是使用「地圖」的想法很好 – 2009-11-05 22:25:27

+0

這是行不通的嗎? 'map {$ columns [$ _] - > as_trimmed_text} 1,3,5,7,9' – 2009-11-05 22:31:43

+1

你可能需要在你正在做的事情中添加更多的代碼;這對我來說是正確的。 – 2009-11-05 22:31:56

回答

1

首先,如果您對地圖輸出不感興趣,則不應使用地圖。地圖,像grep,排序等是一個過濾器。如果你不想輸出,使用foreach。

但是你是對的,地圖的設計正是爲了解決這類問題。這會給你想要的輸出,儘管它不使用數組切片。

@trimmed_columns = map { $column[$_]->as_trimmed_text } (1, 3, 5, 7, 9); 

Robert P's answer更好地解釋了爲什麼原來沒有工作。

+0

-1。這個答案只有真實的陳述,它有有效的代碼,但它沒有解決這個問題,這個問題是關於使用具有**數組slice **的'map'的問題。它也沒有提供原始代碼錯誤的解釋。 – 2009-11-05 23:49:47

+1

我想你在技術上是正確的。我更關心的是以最正確的方式爲他的問題提供解決方案,而不是回答發佈的確切問題。 由於數組切片被perl視爲不可變列表,因此使用map對其進行內聯修改(您不應該這樣做)將是錯誤的解決方法。 我會修改我的答案,使其更具表現力。 – Bob 2009-11-06 00:13:20

+1

問題中的代碼不會修改任何內容,並且它對數組切片的使用沒有任何問題...... – hobbs 2009-11-06 04:52:06

5

map看起來我的權利。你確定第二個應該說@columns而不是@column?你是否打開strict來捕捉變量名中的拼寫錯誤?

+0

形而上學的+1因爲我仍然沒有upvotes。詛咒! – 2009-11-05 22:26:41

+4

'使用嚴格的岩石' – 2009-11-05 22:29:23

+2

什麼是'嚴格的岩石'? – pavium 2009-11-05 22:31:48

1

您在第二個示例@columns中使用另一個變量,但不是@column。嘗試使用下面的代碼:

map { $_->as_trimmed_text } @column[1, 3, 5, 7, 9] 
8

發現:

下面是一些代碼,它模擬什麼應該發生:

use strict; 
use warnings; 

package Text; 

sub new 
{ 
    my $class = shift; 
    my $text = shift; 
    return bless { TEXT => $text }, $class; 
} 

sub as_trimmed_text 
{ 
    my $self = shift; 
    my $text = $self->{TEXT}; 
    $text =~ s/^\s*(.*?)\s*$/$1/; 
    return $text; 
} 

package main; 

my @texts = (Text->new(' foo '), Text->new(' bar '), Text->new(' baz ')); 

my @trimmed = map { $_->as_trimmed_text() } @texts[1, 2]; 

print "Trimmed were: ", join(',', map { "'$_'" } @trimmed); 

這工作,並且工作正常;我得到:

Trimmed were: 'bar','baz' 

但是,如果我這一行更換地圖:

my @trimmed = map { $_->as_trimmed_text() } @texts[2, 3]; 

突然我得到這樣的輸出:

Can't call method "as_trimmed_text" on an undefined value 

這是因爲 '3' 是超出@texts中有效值的範圍,所以它會自動檢測一個新條目,並使其成爲undef。那麼,你的地圖確實是

undef->as_trimmed_output() 

哪個barfs。我會再次檢查你的數組片段,並確保你沒有獲取可用實際索引之外的值,並且除此之外,請驗證你是否正在處理具有該map的HTML :: Element成員。有關@columns中值的快速Data::Dumper::Dumper將非常有幫助。

例如,如果你再改變你的數組包含

my @texts = (Text->new(' foo '), Text->new(' bar '), ' baz '); 

,並嘗試運行它,我現在讓你的錯誤:

Can't call method "as_trimmed_text" without a package or object reference at map.pl 

所以,仔細檢查,以確保內容你的數組實際上是你試圖調用方法的類的所有祝福實例。

+0

像這樣的遲到(可能)正確答案會讓我很傷心,因爲我已經失去了upvotes。 – 2009-11-05 22:45:37

+0

@Chris:你說了很多(你希望你可以upvote等)。爲什麼不在第二天簡單地回來,並upvote? – Telemachus 2009-11-06 01:20:36

+0

這是最可能的答案,排除錯字假設:) – hobbs 2009-11-06 04:53:29

相關問題