Last active
June 30, 2019 18:00
-
-
Save philippbayer/5881767 to your computer and use it in GitHub Desktop.
A perverted kind of natural sort in golang
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"sort" | |
"strconv" | |
"strings" | |
"unicode" | |
) | |
// Mostly based on http://golang.org/pkg/sort/#example__sortKeys | |
// Since name is a string, don't need to implement fancy structs | |
type By func(name1, name2 string) bool | |
func (by By) Sort(names []string) { | |
ps := &nameSorter{ | |
names: names, | |
by: by, | |
} | |
sort.Sort(ps) | |
} | |
type nameSorter struct { | |
names []string | |
by func(name1, name2 string) bool | |
} | |
func getNumber(name string) (new_s int) { | |
// Need a key to sort the names by. In this case, it's the number contained in the name | |
// Example: M23abcdeg ---> 23 | |
// Of course, this tends to break hideously once complicated stuff is involved: | |
// For example, 'ülda123dmwak142.e2dööööwq,' what do you sort by here? | |
// Could be 123, could be 142, or 2, could be 1231422 (this takes the last case) | |
s := make([]string, 0) | |
for _, element := range name { | |
if unicode.IsNumber(element) { | |
s = append(s, string(element)) | |
} | |
} | |
new_s, err := strconv.Atoi(strings.Join(s, "")) | |
if err != nil { | |
log.Fatal(err) // Just die | |
} | |
return new_s | |
} | |
// Need some inbuilt methods | |
func (s *nameSorter) Swap(i, j int) { | |
s.names[i], s.names[j] = s.names[j], s.names[i] | |
} | |
func (s *nameSorter) Len() int { | |
return len(s.names) | |
} | |
func (s *nameSorter) Less(i, j int) bool { | |
return s.by(s.names[i], s.names[j]) | |
} | |
func main() { | |
// closure to sort by | |
name_number := func(name1, name2 string) bool { | |
return getNumber(name1) < getNumber(name2) | |
} | |
fmt.Println("Before:") | |
example_slice := []string{"9999", "123bla", "1bla", "dawjdwa50awdnwdkj"} | |
fmt.Println(example_slice) | |
By(name_number).Sort(example_slice) | |
fmt.Println("After:") | |
fmt.Println(example_slice) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment