2009-08-14 41 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);