我对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.
].
提前感谢您的帮助!
答案 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]
变化是:
=
代替==
(不是什么大不了的事)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:
在您的代码中出现了三次。
修改强>
唉!我上面的版本与您的版本不相同,因为如果数字除以'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]