2009-08-14 65 views
1

我在這裏聞到一些不好的東西?我該如何重構這個重複的「if」塊?

 
    if ($col == 24) { 
     $buffer{'Y'} = trim($val); 
     return; 
    } 

    if ($col == 25) { 
     $buffer{'Z'} = trim($val); 
     return; 
    } 

    if ($col == 26) { 
     $buffer{'AA'} = trim($val); 
     return; 
    } 

    if ($col == 27) { 
     $buffer{'AB'} = trim($val); 
     return; 
    } 
+1

一兩件事:我「臭」一些在Excel自動化在那裏(列Z到AA ...嗯!)可能你想要一個特定列號的命名列。肯定也看看Tanktalus的回答。 – 2009-08-14 03:27:08

+0

這應該在dailyWTF上。它很臭。 – Axeman 2009-08-14 06:17:14

回答

14

名字看起來很可疑了。如果您正在循環訪問列,請嘗試使用magiC++運算符。

my $colname = 'A'; 
for (0..$#cols) 
{ 
    # do stuff with $colname 
    $buffer{$colname} = trim($val); 
    ++$colname; 
} 

如果不是,似乎是這裏的圖案,你可以利用從十進制(數字)轉換號碼字母。你會做你一個數字號碼轉換爲十進制以同樣的方式,不同之處在於你會使用字符AZ,基地26,而不是0-9,基座10喜歡的東西:

sub colname 
{ 
    my $num = shift; 
    my $name = ''; 
    while ($num) 
    { 
    $name .= chr(ord('A') + $num % 26); 
    $num /= 26; 
    } 
    reverse $name; 
} 

(未經測試)此算法與語言無關。它並沒有特別的利用好處,但作爲一般情況奇妙地工作。

更新:我告訴過你,這是未經測試的。 j_random_hacker指出了這個thinko,我已經糾正了它。謝謝!

+0

恰恰是我需要的 - 謝謝! – est 2009-08-14 03:31:42

+2

不應該最後一行讀取「reverse $ name;」?否則很好。 – 2009-08-14 04:52:25

+1

-1引起你的注意...;) – 2009-08-14 06:06:00

0

在其他編程語言中,您可以使用switch語句。 This page有幾種方法來模擬Perl(5+)中的switch語句。

當然,如果我打算仔細閱讀這個問題,我不會建議一個switch語句來處理輸出到輸出的特定序列

+1

perl 5.10.x具有默認開關(對於較早版本,使用Switch.pm)。但是,switch語句,imho,和重複一樣醜陋 - 只是看起來更乾淨。 – est 2009-08-14 03:12:20

+0

這裏不需要switch語句,因爲每個選項都具有相同的基本功能。正如George Phillips所示,散列工作正常。 – friedo 2009-08-14 03:47:32

2

找到一種將「$ col」編碼成表示散列中該列的字符串的方法(即,將25轉換成'Z'並將26轉換成'AA'等)。

sub encodeCol { 
    ... 
} 

$buffer{encodeCol($col)} = trim($val); 
+0

+1因爲比我快, – willoller 2009-08-14 03:03:57

12

關聯數組在這些情況下工作得很好。首先初始化:

my %colToBuffer = (24 => 'Y', 25 => 'Z', 26 => 'AA', 27 => 'AB'); 

然後代碼可以是:

if (exists $colToBuffer{$col}) 
{ 
    $buffer{$colToBuffer{$col}} = trim($val); 
} 

季節的味道。

+1

+1,非常簡潔!雖然,如果你不得不初始化很多值,可能不太好。 – dreamlax 2009-08-14 03:07:28

+1

我輸入了等價物,但在Python中,因爲我不知道Perl。我只會給你+1。 – FogleBird 2009-08-14 03:08:47

-1

在C類僞代碼,編碼列編號:

alphabet[1:26] = {'A','B','C','D',...,'Z'} 
col = col + 1; // so that 1=A, ..., 26=Z 
string = ""; 

while(col > 0) { 
    letterRank = col % 26; // % for modulo 
    string = concatenate(alphabet[letterRank], string); 
    col = col/26; // integer division 
} 
1

如果$ col在24..27中,則計算相應的字母,並設置合適的哈希條目。這裏有兩種方法可以做到這一點,取決於你是否要保存一些字符或保存幾個字節:

24 <= $col && $col <= 27 and $buffer{('A'..'AB')[$col]} = trim($val); 

24 <= $col && $col <= 27 and $buffer{('Y'..'AB')[$col - 24]} = trim($val);