我有三个整数值,比如说
h := 3.
m := 19.
s := 8.
我想生成字符串'03:19:08'
。我知道如何将数字转换为字符串,如果需要,甚至用零填充它。所以作为第一遍,我写了这个绝对可怕的代码:
h < 10 ifTrue: [hs := '0', (h asString)] ifFalse: [hs := h asString].
m < 10 ifTrue: [ms := '0', (m asString)] ifFalse: [ms := m asString].
s < 10 ifTrue: [ss := '0', (s asString)] ifFalse: [ss := s asString].
Transcript show: hs, ':', ms, ':', ss.
Transcript nl.
现在显然我需要清理它,所以想知道,其中最惯用的Smalltalk方法将在这里。它可能是(显然不合法的Smalltalk):
aCollectionWithHMS each [c | padWithZero] join ':'
我发现了一个关于流的讨论,其中一个打印方法采用了separatedBy
参数,但是没有一种更简单的方法可以用字符串做事吗?
或许有一种更优雅的方式来填充三个组件然后我可以返回hs, ':', ms, ':', ss
?
或者,是否存在所有Smalltalks共有的POSIX时间格式(或类似内容)的接口?我知道GNU Smalltalk可以链接到C但是对于这个简单的问题恕我直言太过分了。
修改
我离得更近了一点:
z := {h . m . s} collect: [:c | c < 10 ifTrue: ['0', c asString] ifFalse: [c asString]].
(Transcript show: ((z at: 1), ':', (z at: 2), ':', (z at: 3))) nl.
但收集元素的直接访问让我感到难过。我找到了一个page documenting the joining method asStringWith
但该方法不受支持,似乎在GNU Smalltalk中。
答案 0 :(得分:3)
以下是在Pharo中执行此操作的方法:
String streamContents: [:stream |
{h.m.s}
do: [:token | token printOn: stream base: 10 nDigits: 2]
separatedBy: [stream nextPut: $:]]
说明:
streamContents:
消息回答正式阻止参数WriteStream
所代表的stream
的内容。
do:separatedBy:
消息列举了令牌h
,m
和s
,为每个令牌评估do:
块并插入评估连续令牌之间的第二个区块。
printOn:base:nDigits:
消息转储stream
基础10
表示token
填充为2
位数。
如果您使用的方言没有printOn:base:nDigits:
方法(或其任何适当的变体),您可以执行以下操作:
String streamContents: [:stream |
{h.m.s}
do: [:token |
token < 10 ifTrue: [stream nextPut: $0].
stream nextPutAll: token asString]
separatedBy: [stream nextPut: $:]]
最后,如果您认为自己会经常使用此功能,我建议您将hhmmss
消息添加到Time
(实例方),如上所述,使用self hours
代替{ {1}}等等然后发送
h
假设您拥有这三个数量而不是(Time hour: h minute: m second: s) hhmmss
个对象,这将是不寻常的。否则,你只需要像
Time
<强>附录强>
这是另一种适用于任何方言的方式:
aTime hhmmss
{h.m.s}
inject: ''
into: [:r :t | | pad colon |
pad := t < 10 ifTrue: ['0'] ifFalse: [''].
colon := r isEmpty ifTrue: [''] ifFalse: [':'].
r , colon, pad, t asString]
方法从inject:into:
参数(在本例中为空inject:
)构建其结果,并继续用正值块String
替换正式块参数r
。上一次迭代。第二个正式参数t
将替换为每次迭代的相应元素。
ADDENDUM 2
time := '00:00:00' copy.
{h asString. m asString. s asString} withIndexDo: [:t :i |
time at: i - 1 * 3 + 2 put: t last.
t size = 2 ifTrue: [time at: i - 1 * 3 + 1 put: t first]].
^time
copy
是确保文字未被修改所必需的。