【问题标题】:extract a substring from a string in smalltalk (squeak)从 smalltalk 中的字符串中提取子字符串(吱吱声)
【发布时间】:2014-12-07 14:33:30
【问题描述】:

我正在尝试从一个字符串中提取一个子字符串,该字符串是两个分隔符之间的子字符串 即它应该定义如下:

substring: aString delimiter: aDelimiter

例如,如果我得到这一行:

substring: 'dddd#sss#dddd' delimiter: '#'

函数应该返回“sss”。

这是我一直在尝试的,但没有奏效:

substring: aString delimiter: aDelimiter
|index temp1 temp2 sz arr str|
      arr := aString asArray.
      sz := arr size.
      index := arr lastIndexOf: aDelimiter.
      temp1 := arr first: (sz - index +1).
      index := temp1 lastIndexOf: aDelimiter.
      sz :=temp1 size.
      temp2 := temp1 first: (sz - index).
      str := temp2 asString.
      ^str.

我不知道它是否值得一提,但它应该是一个类方法。

【问题讨论】:

  • 你的代码在做什么?为什么它不起作用?

标签: oop smalltalk squeak


【解决方案1】:

您的基本问题是参数 aDelimiter 是字符串而不是字符。你想用 $# 而不是 '#' 来调用它。

现在介绍一些更简单的方法。可能最简单的是使用 subStrings: 方法:

('dddd#sss#dddd' subStrings: '#') at: 2

这有一个缺点,它将整个字符串提取为由 # 字符分隔的子字符串,这可能超出您的需要。

下一个最简单的选择是使用流:

'dddd#sss#dddd' readStream upTo: $#; upTo: $#

该代码仅提取您需要的部分。

【讨论】:

    【解决方案2】:

    正如 David 所指出的,您离工作代码不远了。但我只想指出,这是非常程序化的。 Smalltalk 和一般的 OOP 的许多魔力在于编写漂亮、易于理解的代码,将意图揭示消息发送到适当对象的社区。这包括依靠图像中已经存在的对象。我想不出有什么时候我不得不为了这样一个简单的任务走这么低的水平。阅读许多很棒的 OOP 参考资料之一会很棒。我最喜欢的是A Mentoring Course on Smallalk

    我认为大卫的解决方案是正确的。我个人喜欢second而不是at: 2,但感觉很挑剔,可能是个人喜好('dddd#sss#dddd' subStrings: '#') second

    【讨论】:

    • 我也喜欢second。它比at: 2 更清晰。它不是在所有 Smalltalk 方言中,但很容易添加。
    【解决方案3】:

    虽然我喜欢上面的两个答案,但您可能还想考虑另一个更接近您最初尝试的答案,并且比其他答案更有效,因为它只创建您正在寻找的对象(例如,没有中间流)

    substringOf: aString delimitedBy: aCharacter
        | i j |
        i := aString indexOf: aCharacter.
        j := aString indexOf: aCharacter startingAt: i + 1.
        ^aString copyFrom: i + 1 to: j - 1
    

    (注意顺便说一句,我还建议使用稍微不同的选择器。)

    您要考虑的另一个方面是,如果aCharacter 不在aString 中,该方法应该如何反应,它只有一次或者它出现了三个或更多。类似于:

    substringOf: aString delimitedBy: aCharacter
        | i j |
        i := aString indexOf: aCharacter.
        i = 0 ifTrue: [^''].
        j := aString indexOf: aCharacter startingAt: i + 1.
        j = 0 ifTrue: [^''].
        ^aString copyFrom: i + 1 to: j - 1
    

    但同样,如果您的情况不是性能问题,那么请选择 readStream upTo upTo 答案,因为它可能是最好的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      相关资源
      最近更新 更多