I'm having trouble sorting strings by character (to check whether two strings are anagrams, I want to sort both of them, and check for equality).
I can get a []rune
representation of the string s
like this:
runes := make([]rune, len(s))
copy(runes, []rune(s))
And I can sort ints like this
someInts := []int{5, 2, 6, 3, 1, 4} // unsorted
sort.Ints(someInts)
But rune
is just an alias for int32
so I should be able to call
sort.Ints(runes)
However, I get the error:
cannot use runes (type []rune) as type []int in function argument
So... how do I sort a slice of int32, int64, or int*?
EDIT: I did get my runes sorted, but boy, this is ugly.
type RuneSlice []rune
func (p RuneSlice) Len() int { return len(p) }
func (p RuneSlice) Less(i, j int) bool { return p[i] < p[j] }
func (p RuneSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func sorted(s string) string {
runes := []rune(s)
sort.Sort(RuneSlice(runes))
return string(runes)
}
So basically if you have a slice of whatever, you'll have to wrap it in a type that implements sort.Interface
. All those implementations will have the exact same method bodies (like sort.IntSlice
and sort.Float64Slice
). If this is really how ugly this has to be then why didn't they provide these WhateverSlice wrappers in the sort
package? The lack of generics start to hurt very badly now. There must be a better way of sorting things.
sort.Interface
. Now, how do you propose to automagically get theLen
and friends of anything you know nothing about in advance (at compile time)??? IOW, your rant is not rational. – FrescoBucketOfFish
instances out of the box.sort.Interface
seems like a nice abstraction for these cases (although I probably want to keep my Fishes in slices as well, instead of some custom container). I just find it strange that such a basic use case (slice of a basic type) is not covered by the standard library. – Clarendonmake
statement should useutf8.RuneCountInString
(fromunicode/utf8
) rather thanlen
;len
counts the number of bytes, not the number of runes. – Hydrophyte