Sort indices of slice in Go/Golang

Issue

I want to sort the index of elements rather than sorting the slice. For []string{"dog","cat","apple","bat"} I want to get []int{2,3,1,0}

package main

import (
    "fmt"
    "sort"
    "strings"
)

func main() {
    arr := []string{"dog","cat","apple","bat"}
    n := len(arr)
    indices := make([]int, n)
    for i:=0;i<n;i++{
        indices[i]=i
    }
    sort.Slice(indices, func(i,j int) bool {return strings.Compare(arr[i],arr[j])<0})
    fmt.Println(arr, indices) // [dog cat apple bat] [2 1 0 3]
    
    sort.Slice(arr, func(i,j int) bool {return strings.Compare(arr[i],arr[j])<0})
    fmt.Println(arr) //[apple bat cat dog] 
}

Solution

The indices your less() function gets are indices of the sortable slice (indices), not another (arr) slice.

So use i and j to index indices. The result is of course is an index to be used for the arr slice (that’s your definition of the indices slice), so you get the comparable elements using the expressions arr[indices[i] and arr[indices[j]].

And don’t use strings.Compare(), simply compare strings using the less < operator. For details, see Go compare strings.

sort.Slice(indices, func(i, j int) bool {
    return arr[indices[i]] < arr[indices[j]]
})

With this change you get your expected output (try it on the Go Playground):

[dog cat apple bat] [2 3 1 0]
[apple bat cat dog]

Answered By – icza

Answer Checked By – Candace Johnson (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.