Search code examples
smalltalkpharo

SortedCollection that ignores case in strings


By default, a SortedCollection is case sensitive (which seems surprising to me given how Strings are mostly used today), e.g.,

list := #('z' 'c' 'C' 'A' 'a').
slist := list asSortedCollection. "a SortedCollection('A' 'C' 'a' 'c' 'z')"

With Spotter, I found caseInsensitiveLessOrEqual: but wasn't sure how to use it with a SortedCollection. How can I easily get a sorted collection that ignores case?


Solution

  • asSortedCollection: takes a sort block, too:

    list := #('z' 'c' 'C' 'A' 'a').
    slist := list asSortedCollection: 
        [ :a :b | a caseInsensitiveLessOrEqual: b ]. "a SortedCollection('a' 'A' 'C' 'c' 'z')"
    

    Edit Here's a solution to get a consistent order (this is ugly, I got it from diving into caseInsensitiveLessOrEqual:)

    caseInsensitiveCompare := [ :a :b | | result | 
        result := a compare: b caseSensitive: false.
        "equal ignoring case" 
        result = 2 ifTrue: [ a compare: b caseSensitive: true ].
        "less than, so return true (else return false since result=2)" 
        result = 1  ].
    
    slist := list asSortedCollection: caseInsensitiveCompare. 
    "a SortedCollection('A' 'a' 'C' 'c' 'z')"