Smalltalk多类型数组排序报错:ByteString Class(Object)>>DoesNotUnderstand
解决Smalltalk混合类型数组排序报错问题
你尝试对包含字符串和数字的数组排序时,出现ByteString Class(Object)>>DoesNotUnderstand错误,原代码如下:
| x sortedX | x := #('bb' 10 'aa' 2 'cc' 3 5). sortedX := x asSortedCollection: [:y :z | (y class = z class) ifTrue: [y < z] ifFalse: [y class < z class] ]. Transcript show: sortedX; cr.
错误原因
Smalltalk的Class类默认没有实现<比较方法,当你在不同类型元素比较时执行y class < z class,系统找不到对应的消息处理逻辑,因此抛出DoesNotUnderstand异常。
解决方案
可以通过比较类的名称字符串来替代类本身的比较——字符串类型原生支持<操作。如果需要数字优先排在字符串前面,还可以额外增加类型判断逻辑。
基础修复版本
| x sortedX | x := #('bb' 10 'aa' 2 'cc' 3 5). sortedX := x asSortedCollection: [:y :z | (y class = z class) ifTrue: [y < z] ifFalse: [y class name < z class name] ]. Transcript show: sortedX; cr.
实现数字优先的版本
如果你希望严格按照数字在前、字符串在后的顺序排序,可调整为:
| x sortedX | x := #('bb' 10 'aa' 2 'cc' 3 5). sortedX := x asSortedCollection: [:y :z | (y class = z class) ifTrue: [y < z] ifFalse: [ y isNumber ifTrue: [true] ifFalse: [z isNumber ifTrue: [false] ifFalse: [y class name < z class name]] ] ]. Transcript show: sortedX; cr.
运行后即可得到你预期的结果:#(2 3 5 10 'aa' 'bb' 'cc')
内容的提问来源于stack exchange,提问作者yoav28
相关产品推荐
相关产品推荐

