Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go sort a slice of runes?

Tags:

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.

like image 955
andras Avatar asked Aug 11 '13 10:08

andras


People also ask

How do you sort a slice in go?

In Go language, you can sort a slice with the help of Slice() function. This function sorts the specified slice given the provided less function. The result of this function is not stable. So for stable sort, you can use SliceStable.

How do I sort a string slice in go?

To sort a slice of strings in Go programming, use sort package. sort package offers sorting for builtin datatypes and user defined datatypes, through which we can sort a slice of strings. The sorting or strings happen lexicographically. Meaning a is less than b , b is less than c , and so on.

How does sort slice work Golang?

You simply pass an anonymous function to the sort. Slice function. This will sort in ascending order, if you want the opposite, simply write a[i] > a[j] in the anonymous function. @LewisChan it is not restricted on int types; the int parameters are indexes to the slice, which can be a slice of strings.

What is rune slice?

When you convert a string to a rune slice, you get a new slice that contains the Unicode code points (runes) of the string. For an invalid UTF-8 sequence, the rune value will be 0xFFFD for each invalid byte.


2 Answers

Use sort.Sort(data Interface) and implement sort.Interface, see the examples on package documentation.

You cannot use rune which is int32 as int. Check the comment of int.

int is a signed integer type that is at least 32 bits in size. It is a distinct type, however, and not an alias for, say, int32.

like image 161
Grzegorz Żur Avatar answered Nov 09 '22 19:11

Grzegorz Żur


Note: Go 1.8 will introduce helpers for sorting slices.
See issue 16721 and commit 22a2bdf by Brad Fitzpatrick

var strings = [...]string{"", "Hello", "foo", "bar", "foo", "f00", "%*&^*&^&", "***"}

func TestSlice(t *testing.T) {
    data := strings
    Slice(data[:], func(i, j int) bool {
        return data[i] < data[j]
    })
}
like image 33
VonC Avatar answered Nov 09 '22 20:11

VonC