2017-05-23 1 views
1

J'ai trois valeurs entières, direTemps de mise en forme (HH: MM: SS) dans un dialecte Smalltalk

h := 3. 
m := 19. 
s := 8. 

je voudrais produire la chaîne '03:19:08'. Je sais comment transformer un nombre en chaîne, et même le remplir avec un zéro si nécessaire. Donc, en tant que premier passage j'ai écrit ce code absolument horrible:

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. 

Maintenant, évidemment, je dois nettoyer ce et me demandais si, entre autres ce que l'approche la plus Smalltalk idiomatiques serait ici. Se pourrait-il quelque chose comme (non Smalltalk juridique évidemment):

aCollectionWithHMS each [c | padWithZero] join ':' 

Je trouve une discussion sur les flux avec une méthode d'impression en prenant un argument separatedBy mais ne serait pas là un moyen plus simple de faire les choses simplement avec des cordes?

Ou peut-être il y a une façon plus élégante de tamponner les trois composants et puis je pourrais juste retourner hs, ':', ms, ':', ss?

Ou existe-t-il une interface pour le formatage POSIX (ou similaire) commune à tous les Smalltalks? Je sais que GNU Smalltalk peut relier à C mais c'est beaucoup trop pour ce problème simple à mon humble avis.

EDIT

Je suis un peu plus près:

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. 

Mais l'accès direct des éléments de collecte me rend triste. J'ai trouvé un page documenting the joining method asStringWith mais cette méthode n'est pas supportée, il semble dans GNU Smalltalk.

Répondre

3

Voici une façon de le faire dans Pharo:

String streamContents: [:stream | 
    {h.m.s} 
    do: [:token | token printOn: stream base: 10 nDigits: 2] 
    separatedBy: [stream nextPut: $:]] 

Explication:

  1. Les réponses de message streamContents: avec le contenu du WriteStream représentés par l'argument bloc formel stream.

  2. Le message do:separatedBy: énumère les jetons h, m et s évaluant le bloc do: pour chacun d'eux, et l'insertion de l'évaluation du deuxième bloc entre les jetons consécutifs.

  3. Le message printOn:base:nDigits: décharges sur la stream la base de la représentation 10token rembourré pour 2 chiffres.

Si le dialecte que vous utilisez ne pas la méthode printOn:base:nDigits: (de celui-ci ou de toute variation appropriée), vous pouvez effectuer les opérations suivantes:

String streamContents: [:stream | 
    {h.m.s} 
    do: [:token | 
     token < 10 ifTrue: [stream nextPut: $0]. 
     stream nextPutAll: token asString] 
    separatedBy: [stream nextPut: $:]] 

Enfin, si vous pensez que vous serez en utilisant ce beaucoup, je recommande d'ajouter le message hhmmss-Time (côté exemple), mis en œuvre comme ci-dessus avec self hours au lieu de h, etc., il serait alors question d'envoyer

(Time hour: h minute: m second: s) hhmmss 

en supposant que vous avez ces trois quantités au lieu d'un objet Time, ce qui serait inhabituel. Dans le cas contraire, vous ne devez quelque chose comme

aTime hhmmss 

ADDENDA

Voici une autre façon qui fonctionne sur tout dialecte:

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

La méthode inject:into: builds le résultat de l'argument inject: (le vide String dans ce cas) et continue à remplacer le forma l bloque l'argument r avec la valeur de l'itération précédente. Le second argument formel t est remplacé par l'élément correspondant de chaque itération.


ADDENDA 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 

Le copy est nécessaire pour faire en sorte que n'est pas modifié le littéral.

+0

Ça a l'air bien. Je suis allé avec l'addendum 1, mais j'ai utilisé '{''. h. m. s} fold: "Je n'aurais pas pu continuer sans cette idée. –