Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 431
Fuhrmanator Avatar asked May 07 '19 09:05

Fuhrmanator


People also ask

How to sort an array of strings ignoring the 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.

How do I sort data using the sort () method?

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:

What is the difference between sorted list classes and sorted dictionaries?

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.

How do you sort a list of elements?

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.


Video Answer


2 Answers

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')"
like image 58
Fuhrmanator Avatar answered Oct 24 '22 23:10

Fuhrmanator


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')"
like image 41
tukan Avatar answered Oct 24 '22 22:10

tukan