1

我创建了一个 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 语句之后的第二个迭代循环中正确分离了我的语句?我真的很困惑我做错了什么。任何帮助,将不胜感激!

4

2 回答 2

1

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

(您可能还想考虑用 do:aBlock 替换您的 while - 这更简洁,更 Smalltalk-y)

于 2012-04-24T19:54:32.010 回答
1

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

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

请注意,如果输入中有空字符串,这将失败

于 2012-05-02T09:31:09.577 回答