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
+20k Golang : Read directory content with os.Open
+19.2k Golang : Measure http.Get() execution time
+45.3k Golang : Read tab delimited file with encoding/csv package
+3.6k Detect if Google Analytics and Developer Media are loaded properly or not
+10.1k Golang : Select region of interest with mouse click and crop from image
+8.7k nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
+10.8k Golang : How to pipe input data to executing child process?
+7.5k Golang : Sort words with first uppercase letter
+7.2k Golang : Convert(cast) io.Reader type to string
+7.7k Golang : How To Use Panic and Recover
+5.6k AWS S3 : Prevent Hotlinking policy
+14.7k Golang : How do I get the local IP (non-loopback) address ?