【问题标题】:First n characters of string or whole string; without SubscriptOutOfBounds字符串或整个字符串的前 n 个字符;没有 SubscriptOutOfBounds
【发布时间】:2019-02-04 12:20:44
【问题描述】:

在 Pharo 7 中,我试图获取字符串的第一个字符数,或者只是整个字符串(如果请求的字符数超过字符串的长度)。

但是,以下示例会导致错误,而我只是希望它返回整个字符串:

    'abcdef' copyFrom: 1 to: 30. "=> SubscriptOutOfBounds Error"
    'abcdef' first: 30. "=> SubscriptOutOfBounds Error"
    'abcdef' first: 3. "=> 'abc'; OK"

如果请求的长度超过字符串长度,是否有一种方法将只返回整个字符串?

作为一种解决方法,我做了以下操作,首先检查字符串的长度,如果长度超过最大长度,只发送first:,但这不是很优雅:

label := aTaskbarItemMorph label size < 30 ifTrue: [ aTaskbarItemMorph label ] ifFalse: [ aTaskbarItemMorph label first: 30 ].

【问题讨论】:

    标签: smalltalk pharo


    【解决方案1】:

    MethodFinder 救援

    我们还应该记住,对于这种情况,我们在 Pharo 中有 MethodFinder。您可以通过评估您拥有的示例来使用它。在我们的例子中

    MethodFinder methodFor: #(('abcdef' 30) 'abcdef' ('abcdef' 3) 'abc')
    

    会产生

    "'(data1 contractTo: data2) (data1 truncateTo: data2) '"
    

    其中包含已经提到的#truncateTo: 并添加了#contractTo:。请注意,后者实现了其他风格的缩短技术,即

    'abcdef' contractTo: 6 "'a...f'"
    

    可能不是您今天想要的,而是一条可能在未来证明有用的信息。


    语法

    MethodFinder 的语法需要一个长度为 2 * #examplesArray,其中每个示例都由一对(输入参数结果)组成。

    有趣的是,Squeak 大括号可以很容易地提供动态创建的示例:

    input := 'abcdef'.
    n := 1.
    MethodFinder methodFor: {
         {input. input size + n}. input.
         {input. input size - n}. input allButLast
    }
    

    还会找到truncateTo:

    【讨论】:

      【解决方案2】:

      字符串>>truncateTo:

      'abcdef' truncateTo: 30. "'abcdef'"
      'abcdef' truncateTo: 3. "'abc'"
      

      【讨论】:

        【解决方案3】:

        默认情况下,我在String 类或其超类中看不到任何此类方法。您的解决方法是一个很好的解决方案。

        另一种更短的解​​决方法是使用min: 来选择字符串的大小或有限数量的字符。例如:

        string := '123456'.
        label := string first: (string size min: 5).
        

        另一种解决方案是在 String 类中添加一个扩展方法来满足您的需求。因此,该方法将被添加到 String 类中,但放置在您的包中。例如:

        String>>atMost: numberOfElement
            ^ self size < numberOfElement 
                ifTrue: [ self ] 
                ifFalse: [ self first: numberOfElement ]
        

        然后以下将起作用:

        string := '123456'.
        string atMost: 2.  "'12'"
        string atMost: 10. "'123456'"
        

        添加扩展方法时,您可以在其名称中添加前缀以避免可能的冲突,例如,如果稍后将在 Pharo 中添加方法 atMost:,或者如果另一个包也定义了这样的扩展方法。

        【讨论】:

          【解决方案4】:

          这是一个简单的表达式,可以带来你想要的:

          aString readStream next: n
          

          【讨论】:

            猜你喜欢
            • 2010-12-28
            • 2021-12-09
            • 2011-01-10
            • 1970-01-01
            • 2011-12-04
            • 1970-01-01
            • 2012-02-19
            • 1970-01-01
            相关资源
            最近更新 更多