Smalltalk中的多个ifs

时间:2015-02-21 21:11:06

标签: refactoring conditional-statements smalltalk pharo

我对smalltalk真的很陌生,仍在努力找出基本的东西。下面是我写的一个简单程序。 它应该打印" a"如果数字可以除以5," b"如果可以除以3," ab"如果可以除以5和3.在任何其他情况下,程序只打印数字本身。 它肯定是这样的,但我觉得代码不是很漂亮 - 我想避免第三个"如果",但我真的不确定如何。 你会如何重构这个?

1 to: 100 do: [ :i | 
  (i % 5 == 0)
  ifTrue: [ Transcript show: 'a' ].
  (i % 3 == 0)
  ifTrue: [ Transcript show: 'b' ].
  ((i % 3 == 0) or:  (i % 5 == 0))
  ifFalse: [ Transcript show: i ].
  Transcript cr.
].

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

闻起来像Fizz Buzz问题! : - )

Smalltalk(Pharo)中的一种方法我已经看到我喜欢的是使用带有Fizz和/或Buzz词的字典作为值和布尔值来判断它是否可以被3和5整除为键。一旦你有了这个,你只需要查找1到100之间的每个索引的值。哦,并且不要分担并检查余数是否为零 - 它是Smalltalk,所以一个数字应该知道它是否可以被另一个数字整除

| fizzbuzz |
fizzbuzz := Dictionary
    with: #(true true)->'FizzBuzz'
    with: #(true false)->'Fizz'
    with: #(false true)->'Buzz'.
1 to: 100 do: [ :eachIndex |
    Transcript
        show: (fizzbuzz
            at: {eachIndex isDivisibleBy: 3. eachIndex isDivisibleBy: 5}
            ifAbsent: [ eachIndex ]);
        cr]

同时查看一些other examples,有时不同的方法可能非常有教育意义。我会留给你修改代码到'a'/'b'/'ab'的例子。

答案 1 :(得分:1)

首先,我会将您的版本重写为:

1 to: 100 do: [:i |
    i % 5 = 0 ifTrue: [Transcript show: 'a'].
    i % 3 = 0 ifTrue: [Transcript show: 'b'].
    (i % 3 = 0 or: [i % 5 = 0]) ifFalse: [Transcript show: i].
    Transcript cr]

变化是:

  1. 使用=代替==(不是什么大不了的事)
  2. 使用or: [i % 5 = 0]括号
  3. 您可以介绍的另一个变化是

    1 to: 100 do: [:i | | label |
        i % 5 = 0 ifTrue: [label := 'a'].
        i % 3 = 0 ifTrue: [label := 'b'].
        label isNil ifTrue: [label := i].
        Transcript show: label; cr]
    

    请注意,我并没有过多关注IF,而是因为Transcript show:在您的代码中出现了三次。

    修改

    唉!我上面的版本与您的版本不相同,因为如果数字除以'a'5,它就不会打印3

    编辑2

    以下是如何重现原始代码的行为:

    1 to: 100 do: [:i | | label |
        label := ''.
        i % 5 = 0 ifTrue: [label := 'a'].
        i % 3 = 0 ifTrue: [label := label , 'b'].
        label isEmpty ifTrue: [label := i].
        Transcript show: label; cr]