How to rank elements of an integer slice based on their sorted order in Go

1 Answer

0 votes
package main

import (
    "fmt"
    "sort"
)

/*
    Ranking elements of an integer slice based on sorted order in Go
    ----------------------------------------------------------------

    Ranking rules:
    - Lowest value gets rank 1
    - Equal values share the same rank
    - Rank increases only when encountering a new unique value
*/

//
// ------------------------------------------------------------
// Function 1: Print the slice
// ------------------------------------------------------------
func printSlice(slc []int) {
    fmt.Printf("Slice: %v\n", slc)
}

//
// ------------------------------------------------------------
// Function 2: Create a copy of the slice
// ------------------------------------------------------------
func copySlice(slc []int) []int {
    newSlc := make([]int, len(slc))
    copy(newSlc, slc)
    
    return newSlc
}

//
// ------------------------------------------------------------
// Function 3: Sort the slice copy
// ------------------------------------------------------------
func sortSlice(slcCopy []int) {
    sort.Ints(slcCopy)
}

//
// ------------------------------------------------------------
// Function 4: Build a map of value → rank
// ------------------------------------------------------------
func buildRankMap(sortedSlc []int) map[int]int {

    rankMap := make(map[int]int)

    if len(sortedSlc) == 0 {
        return rankMap
    }

    rank := 1
    previous := sortedSlc[0]
    rankMap[previous] = rank

    for i := 1; i < len(sortedSlc); i++ {
        if sortedSlc[i] != previous {
            rank++
        }
        rankMap[sortedSlc[i]] = rank
        previous = sortedSlc[i]
    }

    return rankMap
}

//
// ------------------------------------------------------------
// Function 5: Apply ranks to original slice order
// ------------------------------------------------------------
func applyRanks(original []int, rankMap map[int]int) []int {
    ranked := make([]int, len(original))

    for i, value := range original {
        ranked[i] = rankMap[value]
    }

    return ranked
}

//
// ------------------------------------------------------------
// Main ranking function
// ------------------------------------------------------------
func rankSlice(slc []int) {

    printSlice(slc)

    if len(slc) == 0 {
        return
    }

    slcCopy := copySlice(slc)
    sortSlice(slcCopy)
    rankMap := buildRankMap(slcCopy)
    ranked := applyRanks(slc, rankMap)

    fmt.Printf("Rank:  %v\n", ranked)
}

//
// ------------------------------------------------------------
// MAIN
// ------------------------------------------------------------
func main() {

    slc := []int{33, 99, 10, 25, 47, 11, 77}

    rankSlice(slc)
}


/*
run:

Slice: [33 99 10 25 47 11 77]
Rank:  [4 7 1 3 5 2 6]

*/

 



answered Jun 22 by avibootz

Related questions

...