fzlrhmn
fzlrhmn

Reputation: 461

Sort slice of struct based order by number and alphabetically

I have a slice of struct like this and this data

type Interval struct{
    number     float64
    coordinate string
}

func GetIntervals() []Interval {

    data := []Interval{
        {number: 1, coordinate: "x"},
        {number: 8, coordinate: "y"},
        {number: 2, coordinate: "x"},
        {number: 5, coordinate: "y"},
        {number: 5, coordinate: "x"},
        {number: 6, coordinate: "y"},
        {number: 3, coordinate: "x"},
        {number: 7, coordinate: "y"},
    }
    return data
}

My question is how can I sort []Interval by number and coordinate?

I have tried with below sort method, but it is not as my expectation

data := GetIntervals()
// sort method that I use
sort.Slice(data, func(i, j int) bool {
    return data[i].number < data[j].number
})
[{1 x} {2 x} {3 x} {5 y} {5 x} {6 y} {7 y} {8 y}] // result
[{1 x} {2 x} {3 x} {5 x} {5 y} {6 y} {7 y} {8 y}] // expectation

diff: {5 y} {5 x} should be {5 x} {5 y}

My expectation result is similar with what python has with function sort I appreciate any help

Demo

Upvotes: 2

Views: 71

Answers (1)

hqt
hqt

Reputation: 30266

Your comparator function doesn't compare property coordinate in the situation property number is equal. Hence the position of {5, x} and {5, y} might be non-deterministic if the sorting algorithm is not stable.

Here is the updated version of the comparator function:

sort.Slice(data, func(i, j int) bool {
    if data[i].number != data[j].number {
        return data[i].number < data[j].number
    }
    return data[i].coordinate < data[j].coordinate
})

See Demo with both sort functions

Upvotes: 2

Related Questions