[英]VisualWorks - Find characters in string and replace them
我只有一個字。 起初,只有字母,而不是字母。 因此,例如,單詞“ town”將顯示為“ ????”。 然后用戶猜到字母,如果他釘了,它從變為? 到實際的字母。 例如,如果他猜到t,它將看起來像是“ t ???”。
問題是,我不知道如何遍歷字符串並將其划分為字符。 而且,如果我以某種方式執行此操作,則無法在新字符串中進行更改。
應該看起來像這樣。
word do: [ :c |
c = guessedChar
ifTrue[mask := mask, guessedChar]
ifFalse[mask := mask, '?']
].
mask
初始化為nil,因為word
長度可以更改並且word
為String
。 guessedChar
連接到inputField,但是一次僅包含一個字符。
會更好嗎,對每個guessedChar一次執行一次,還是保留所有猜測的字符的集合並每次運行一次?
一個String
是一個Collection
的Character
對象。 因此,您也可以使用適用於其他集合的相同方法(例如#select:
, #collect:
或#reject:
guessedCharacters := 'ts'.
mask := word collect:[:each | (guessedCharacters includes: each)
ifTrue:[each]
ifFalse:[$?]].
請注意, 't'
是帶有Character
t的String
。 一個Character
可以寫成$
前綴文字字符$t
。
由於String
是SequenceableCollection
的子類,因此可以通過,
連接兩個String。 但是,您不能連接String
和Character
。
相反,您可以使用#copyWith:
將Character
追加到String
。 結果是一個新的String
,它將不會修改現有實例。
你可以用
word doWithIndex: [:c :i | c = guess ifTrue: [mask at: i put: c]]
等效於:
i := 1.
word do: [:c |
c = guess ifTrue: [mask at: i put: c].
i := i + 1]
除了您不必初始化和遞增i
(這更容易出錯和更冗長)外,
附錄
鑒於String
實例無法增長或更改其大小(這是不可變的),我假設可能發生變化的是變量word
。 在這種情況下,您應該相應地初始化mask
,因此兩個字符串始終保持相同的長度。 像這樣:
word: aString
word := aString.
mask := word copy atAllPut: $?
如果您還想保留已經猜到的字符:
word: aString
| guessed |
word := aString.
guessed := mask reject: [:c | c = $?].
mask := word copy atAllPut: $?.
guessed do: [:c | self try: c].
其中#try:
是我們以前使用的方法
try: aCharacter
word doWithIndex: [:c :i | c = aCharacter ifTrue: [mask at: i put: c]]
(如果需要,您可能需要uppercase
)
"initially"
actualWord := 'phlebotomy'.
actualMask := actualWord collect: [:ch| $?].
"after each guess"
word := actualWord readStream.
mask := actualMask readStream.
newMask := WriteStream on: String new.
[ word atEnd
] whileFalse:
[ nextCh := word next = guessedCharcter
ifTrue: [mask skip. guessedCharacter]
ifFalse: [mask next].
newMask nextPut: nextCh
].
actualMask := newMask contents
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.