我怎样才能重构这一系列重复的“if”块?

时间:2009-08-14 02:55:32

标签: perl

我闻到了一些不好的东西?

    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;
    }

6 个答案:

答案 0 :(得分:14)

这些名字看起来也很可疑。如果你循环遍历列,请尝试使用magic ++运算符。

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

如果没有,这里似乎有一种模式可以用来将数字从十进制(数字)转换为字母。你可以像将数字转换为十进制一样,除了你使用字符A-Z,基数26,而不是0-9,基数10.类似的东西:

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

(未经测试)此算法与语言无关。它没有特别利用perlishness,但作为一般案例非常有用。

更新:我告诉过你这是未经测试的。 j_random_hacker指出了思考,我已经纠正过了。谢谢!

答案 1 :(得分:12)

关联数组在这些情况下运行良好。首先初始化:

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

然后代码可以是:

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

品尝季节。

答案 2 :(得分:2)

找到一种方法将“$ col”编码成一个表示散列中该列的字符串(即将25变成'Z',将26变成'AA'等)。

sub encodeCol {
  ...
}

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

答案 3 :(得分: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);

答案 4 :(得分:0)

在其他编程语言中,您使用switch语句。 This page有几种方法可以在Perl(5 +)中模拟switch语句。

当然,如果我不愿意仔细阅读这个问题,我就不会建议使用switch语句处理输出到输出的特定序列

答案 5 :(得分:-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
}