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?
Use the localeCompare () method to compare the strings ignoring the case. The sort () method will return the sorted array. We used the Array.sort method to sort an array of strings ignoring the case. Note that the sort () method sorts the elements of the array in place and returns the sorted array. In other words, it mutates the original array.
The sort () method and the sorted () function take a key argument: The function named in key is called for each value and the return value is used when sorting, without affecting the actual values: To sort Ant before ant, you'd have to include a little more info in the key, so that otherwise equal values are sorted in a given order:
Each class provides properties that return collections containing only the keys or only the values. The following table lists some of the differences between the two sorted list classes and the SortedDictionary<TKey,TValue> class. The properties that return keys and values are indexed, allowing efficient indexed retrieval. No indexed retrieval.
Elements are sorted according to a System.Collections.IComparer implementation (for nongeneric SortedList) or a System.Collections.Generic.IComparer<T> implementation (for the two generic classes). Each class provides properties that return collections containing only the keys or only the values.
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')"
I'm adding the answer to address @Amos M. Carpenter comment - the sorting stability. Your second code is unnecessarily complex. What you could do is add one asSortedCollection
to the list
(which would sort the strings based alphabet position and "capitalness" and you would get consistent solution:
list := #('z' 'c' 'C' 'A' 'a') asSortedCollection.
slist := list asSortedCollection:
[ :a :b | a caseInsensitiveLessOrEqual: b ]. "SortedCollection('a' 'A' 'c' 'C' 'z')"
list := #('z' 'C' 'c' 'A' 'a') asSortedCollection.
slist := list asSortedCollection:
[ :a :b | a caseInsensitiveLessOrEqual: b ]."SortedCollection('a' 'A' 'c' 'C' 'z')"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With