字符串或整个字符串的前 n 个字符;没有下标越界
First n characters of string or whole string; without SubscriptOutOfBounds
在 Pharo 7 中,我试图获取字符串的第一个字符数,或者只是整个字符串(如果请求的字符数超过字符串的长度)。
但是,下面的示例会导致错误,而我只想 return 整个字符串:
'abcdef' copyFrom: 1 to: 30. "=> SubscriptOutOfBounds Error"
'abcdef' first: 30. "=> SubscriptOutOfBounds Error"
'abcdef' first: 3. "=> 'abc'; OK"
是否有一种方法可以在请求的长度超过字符串长度时 return 整个字符串?
作为解决方法,我做了以下操作,首先检查字符串的长度,如果长度超过最大长度,则只发送 first:
,但这不是很优雅:
label := aTaskbarItemMorph label size < 30 ifTrue: [ aTaskbarItemMorph label ] ifFalse: [ aTaskbarItemMorph label first: 30 ].
默认情况下,我在 String
class 或其超classes 中看不到任何此类方法。您的解决方法是一个很好的解决方案。
或者,更短的解决方法是使用 min:
到 select 字符串的大小或有限的字符数。例如:
string := '123456'.
label := string first: (string size min: 5).
另一种解决方案是向 String
class 添加一个扩展方法来执行您想要的操作。因此该方法将添加到 String
class 但放在您的包中。例如:
String>>atMost: numberOfElement
^ self size < numberOfElement
ifTrue: [ self ]
ifFalse: [ self first: numberOfElement ]
那么下面的方法就可以了:
string := '123456'.
string atMost: 2. "'12'"
string atMost: 10. "'123456'"
添加扩展方法时,您可以在它们的名称中添加前缀以避免可能的冲突,例如,如果稍后在 Pharo 中添加方法 atMost:
,或者如果另一个包也定义了这样的扩展方法。
这是一个简单的表达式,可以带来你想要的东西:
aString readStream next: n
String>>truncateTo:
'abcdef' truncateTo: 30. "'abcdef'"
'abcdef' truncateTo: 3. "'abc'"
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 * #examples
的 Array
,其中每个示例都包含一对(输入参数 , 结果).
有趣的是,Squeak 大括号可以轻松提供动态创建的示例:
input := 'abcdef'.
n := 1.
MethodFinder methodFor: {
{input. input size + n}. input.
{input. input size - n}. input allButLast
}
也会找到 truncateTo:
.
在 Pharo 7 中,我试图获取字符串的第一个字符数,或者只是整个字符串(如果请求的字符数超过字符串的长度)。
但是,下面的示例会导致错误,而我只想 return 整个字符串:
'abcdef' copyFrom: 1 to: 30. "=> SubscriptOutOfBounds Error"
'abcdef' first: 30. "=> SubscriptOutOfBounds Error"
'abcdef' first: 3. "=> 'abc'; OK"
是否有一种方法可以在请求的长度超过字符串长度时 return 整个字符串?
作为解决方法,我做了以下操作,首先检查字符串的长度,如果长度超过最大长度,则只发送 first:
,但这不是很优雅:
label := aTaskbarItemMorph label size < 30 ifTrue: [ aTaskbarItemMorph label ] ifFalse: [ aTaskbarItemMorph label first: 30 ].
默认情况下,我在 String
class 或其超classes 中看不到任何此类方法。您的解决方法是一个很好的解决方案。
或者,更短的解决方法是使用 min:
到 select 字符串的大小或有限的字符数。例如:
string := '123456'.
label := string first: (string size min: 5).
另一种解决方案是向 String
class 添加一个扩展方法来执行您想要的操作。因此该方法将添加到 String
class 但放在您的包中。例如:
String>>atMost: numberOfElement
^ self size < numberOfElement
ifTrue: [ self ]
ifFalse: [ self first: numberOfElement ]
那么下面的方法就可以了:
string := '123456'.
string atMost: 2. "'12'"
string atMost: 10. "'123456'"
添加扩展方法时,您可以在它们的名称中添加前缀以避免可能的冲突,例如,如果稍后在 Pharo 中添加方法 atMost:
,或者如果另一个包也定义了这样的扩展方法。
这是一个简单的表达式,可以带来你想要的东西:
aString readStream next: n
String>>truncateTo:
'abcdef' truncateTo: 30. "'abcdef'"
'abcdef' truncateTo: 3. "'abc'"
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 * #examples
的 Array
,其中每个示例都包含一对(输入参数 , 结果).
有趣的是,Squeak 大括号可以轻松提供动态创建的示例:
input := 'abcdef'.
n := 1.
MethodFinder methodFor: {
{input. input size + n}. input.
{input. input size - n}. input allButLast
}
也会找到 truncateTo:
.