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
+21k Golang : Convert string slice to struct and access with reflect example
+13.7k Golang : syscall.Socket example
+17.9k Golang : How to get hour, minute, second from time?
+11k Golang : How to flush a channel before the end of program?
+11.7k Golang : 2 dimensional array example
+13k Golang : Read from buffered reader until specific number of bytes
+21.5k Fix "Failed to start php5-fpm.service: Unit php5-fpm.service is masked."
+8.6k Golang : automatically figure out array length(size) with three dots
+15.8k Golang : How to extract links from web page ?
+18k Golang : Iterating Elements Over A List
+4.5k Fix Google Analytics Redundant Hostnames problem
+8.2k Android Studio : Image button and button example