Squeak String数组和迭代

时间:2012-04-24 19:41:36

标签: arrays string character iteration squeak

我已经创建了一个Array的子​​类,并为它编写了一些迄今为止运行良好的消息。但是,我现在遇到了上一条消息的问题。这是我的代码正文:

startString: charToTest
"Returns a list of all the words that start with a given character"
|  toReturn i j numWords |
i:= 1.
j:= 1.
numWords := 0.
[i <= self size.] whileTrue: [
    (((self at: i) at: 1) = charToTest)
        ifTrue: [numWords := numWords + 1].
    i:= i+1.
].
toReturn := MyArray new: numWords.
i := 1. 
[i <= numWords.] whileTrue: [
    (((self at: i) at: 1) = charToTest)
        ifTrue: [toReturn at: j put: (self at: i). j := j+1].
    i := i + 1.
].
^toReturn

因此,基本上,该方法会查看自身并创建一个新数组,其大小与以该字符开头的单词数相同。然后它再次迭代,并将这些单词放入一个返回的新数组中。我的工作区看起来完全像这样:

|freshArray testArray|
freshArray := MyArray new: 5.
freshArray
    at: 1 put: 'some';
    at: 2 put: 'things';
    at: 3 put: 'are';
    at: 4 put: 'simple';
    at: 5 put: 'things'.
testArray := freshArray startString: $s

当我在工作区中选择此代码并打印它时,该方法几乎正确。但并不完全。由于某种原因,“toReturn”中的第二个插槽未填充。输出如下:

 a MyArray('some' nil)

为什么会这样?我是否在if语句之后的第二个迭代循环中正确地分离了我的语句?我真的很困惑我做错了什么。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

您的第一次迭代计算以给定字符开头的单词数(假设字符串不为空,但您可以稍后再对其进行检查)。到现在为止还挺好。第二次使用该计数(numWords)再次迭代数组 - 这意味着只考虑初始数组的第一个'numWords'槽中的单词。

(你可能也想考虑用do替换你的while:aBlock - 那里不那么混乱,而且更少Smalltalk-y)

答案 1 :(得分:1)

我们倾向于使用更紧凑的形式:

testArray := freshArray select: [:each | charToTest = each first ]

请注意,如果输入

中有空字符串,则会失败