Golang : Sort words with first uppercase letter
Problem:
You use the sort.Strings()
function to sort a slice of words. However, you noticed that words with the first letter in uppercase are not sorted as advertised. For example:
Before: HEre is an Example of how to convert
After: Example HEre a an and convert
The word HEre and Example are not sorted and place in front of the sorted list. Is this a bug or feature? Not sure.
So, how to get the words with first upper case letter sorted?
Solution:
The following code still uses the sort.Strings()
function. However, before sorting... it will first build a map of words that start with first uppercase letter, convert the affected words to lower case and after sorting, it will use the map to replace the back the words in the sorted slice. This example is also useful if you are looking to replace element inside a slice/array that matches a mapping found in hash table.
Here you go!
package main
import (
"fmt"
"regexp"
"sort"
"strconv"
"strings"
"unicode"
)
func removeDelimString(str string) string {
// alphanumeric (== [0-9A-Za-z])
// \s is a white space character
regExp := regexp.MustCompile(`[^[:alnum:]\s]`)
return regExp.ReplaceAllString(str, "")
}
func sortWordsFixed(input string) string {
var sorted sort.StringSlice
originals := map[string]string{}
var final []string
unsorted := strings.Split(removeDelimString(input), " ")
// test each word with first uppercase letter
for k, v := range unsorted {
if unicode.IsUpper(rune(v[0])) {
// tag the words with first uppercase with their index number
// this is to prevent wrong mapping later
originals[strings.ToLower(v)+"["+strconv.Itoa(k)+"]"] = v
sorted = append(sorted, strings.ToLower(v)+"["+strconv.Itoa(k)+"]")
} else {
sorted = append(sorted, v)
}
}
// sort our words -- but all words start first letter in lowercase
sort.Strings(sorted)
// now, let's replaced back the original words with first uppercase character
for _, v := range sorted {
if strings.HasSuffix(v, "]") {
final = append(final, originals[v])
} else {
final = append(final, v)
}
}
return strings.Join(final, " ")
}
func sortWords(input string) string {
var sorted sort.StringSlice
// clean
sorted = strings.Split(removeDelimString(input), " ") // convert to slice
// bug?
// words with initial uppercase letter will not be sorted!!
sort.Strings(sorted)
return strings.Join(sorted, " ")
}
func main() {
text := `HEre is an Example of how to convert lines of text into a slice in golang, sort them in descending order and then display the sorted output`
fmt.Println("Words sort with words with first uppercase letter. Notice that the words are not sorted:")
fmt.Println("Before: ", text)
fmt.Println("After: ", sortWords(text))
fmt.Println("============================================")
fmt.Println("With sortWordsFixed() function, the words with first uppercase letters are now sorted:")
fmt.Println("Fixed: ", sortWordsFixed(text))
}
Output:
Words sort with words with first uppercase letter. Notice that the words are not sorted:
Before: HEre is an Example of how to convert lines of text into a slice in golang, sort them in descending order and then display the sorted output
After: Example HEre a an and convert descending display golang how in in into is lines of of order output slice sort sorted text the them then to
============================================
With sortWordsFixed() function, the words with first uppercase letters are now sorted:
Fixed: a an and convert descending display Example golang HEre how in in into is lines of of order output slice sort sorted text the them then to
References:
See also : Golang : Get all upper case or lower case characters from string example
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+5.6k Unix/Linux : How to test user agents blocked successfully ?
+19.9k Golang : Check if os.Stdin input data is piped or from terminal
+9.8k CodeIgniter : Load different view for mobile devices
+21.9k Golang : Repeat a character by multiple of x factor
+7.9k Golang : Tell color name with OpenCV example
+12k Golang : calculate elapsed run time
+5.2k Golang : What is StructTag and how to get StructTag's value?
+16.6k Golang : How to generate QR codes?
+11.5k Golang : Verify Linux user password again before executing a program example
+28.3k Get file path of temporary file in Go
+10.5k Golang : Get currencies exchange rates example
+15.3k Golang : How to convert(cast) IP address to string?