Smalltalk中的多个if



我真的是smalltalk的新手,还在努力弄清楚基本的东西。下面是我写的一个简单的程序。如果数字可以被5整除,则应该打印"a",如果可以被3整除,应打印"b",如果它可以被5和3整除则应打印"ab"。在任何其他情况下,程序只打印数字本身。它当然是这样工作的,但我觉得代码不是很漂亮——我想避免第三个"if",但我真的不确定如何做到。你将如何重构它?

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.
].

提前感谢您的帮助!

闻起来像个嗡嗡声问题!:-)

我在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]

看看其他一些例子,有时不同的方法可能很有教育意义。我将让您根据您的"a"/"b"/"b"示例调整代码。

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

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]

你可以引入的另一个变化是

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:在代码中出现三次这一事实。

编辑

唉!我上面的版本与你的版本不等效,因为如果数字除以53,它将不会打印'a'

编辑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]

相关内容

  • 没有找到相关文章

最新更新