0

I have two structs defined as below:

// DuplicatedAd format
type DuplicatedAd struct {
    // Ad Identifier
    AdID int `form:"ad_id" json:"ad_id,omitempty" xml:"ad_id"`
    // Parameters of an Ad, can be empty
    AdParams string `form:"ad_params" json:"ad_params,omitempty" xml:"ad_params"`
    // Body of the Ad
    Body string `form:"body" json:"body,omitempty" xml:"body"`
    // Body Duplicate Percentage
    BodyScore float64 `form:"body_score" json:"body_score,omitempty" xml:"body_score"`
    // Category of the Ad
    Category int `form:"category" json:"category,omitempty" xml:"category"`
    // The ad uploaded main image
    Image string `form:"image,omitempty" json:"image,omitempty" xml:"image,omitempty"`
    // Ad Listing ID
    ListID int `form:"list_id" json:"list_id,omitempty" xml:"list_id"`
    // Listing time for the ad
    ListTime string `form:"list_time" json:"list_time,omitempty" xml:"list_time"`
    // the ad Phone number
    Phone string `form:"phone,omitempty" json:"phone,omitempty" xml:"phone,omitempty"`
    // Region of the Ad
    Region int `form:"region" json:"region,omitempty" xml:"region"`
    // Ad Status
    Status string `form:"status" json:"status,omitempty" xml:"status"`
    // Subject of the Ad
    Subject string `form:"subject" json:"subject,omitempty" xml:"subject"`
    // Subject Duplicate Percentage
    SubjectScore float64 `form:"subject_score" json:"subject_score,omitempty" xml:"subject_score"`
    // Type of the Ad
    Type string `form:"type" json:"type,omitempty" xml:"type"`
    // Total Score
    TotalScore float64 `form:"total_score" json:"total_score,omitempty" xml:"total_score"`
}

// CpResponse format
type CpResponse struct {
    // Number of doublets
    Count int `json:"count"`
    // The Doublet Ads to show
    Duplicated []DuplicatedAd `json:"duplicated"`
}

i'm defining a variable var DuplicatedAds = CpResponse{}and in a loop i'm appending some results to it as follow:

DuplicatedAds.Duplicated = append(DuplicatedAds.Duplicated, t)
DuplicatedAds.Count = len(DuplicatedAds.Duplicated)

i wish that the DuplicatedAds.Duplicated be sorted by TotalScore.

i'm new to golang, so after a little research i found out that i must implement theses three functions before i can sort

func (slice DuplicatedAd) Len() int {
    return len(slice)
}

func (slice DuplicatedAd) Less(i, j int) bool {
    return slice[i].TotalScore < slice[j].TotalScore
}

func (slice DuplicatedAd) Swap(i, j int) {
    slice[i], slice[j] = slice[j], slice[i]
}

but when i try to compile i get this errors:

./duplicates.go:165: cannot use DuplicatedAds.Duplicated (type []DuplicatedAd) as type sort.Interface in argument to sort.Sort:
    []DuplicatedAd does not implement sort.Interface (missing Len method)
./types.go:68: invalid argument slice (type DuplicatedAd) for len
./types.go:72: invalid operation: slice[i] (type DuplicatedAd does not support indexing)
./types.go:72: invalid operation: slice[j] (type DuplicatedAd does not support indexing)
./types.go:76: invalid operation: slice[i] (type DuplicatedAd does not support indexing)
./types.go:76: invalid operation: slice[j] (type DuplicatedAd does not support indexing)
./types.go:76: invalid operation: slice[i] (type DuplicatedAd does not support indexing)

How could i have an CpResponse object which his Duplicated array is sorted by DuplicatedAd.TotalScore ?

2 Answers 2

5

Starting from Go 1.8, you can use the following function to sort your slice:

sort.Slice(DuplicatedAds.Duplicated, func(i int, j int) bool {
    return DuplicatedAds.Duplicated[i].TotalScore < DuplicatedAds.Duplicated[j].TotalScore
})

You don't need to define those three functions up there anymore (Len, Less and Swap). Notice how we used the same implementation of Len as a parameter of sort.Slice.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, i forgot to mention that i'm using version 1.5. but i tried slice.Duplicated[i].TotalScore like you mentioned instead of slice[i].TotalScore like i did, and it works
0

cd1 offers a good solution. As for the reason your methods aren't working, it's because they're operating on a single struct and not a slice of structs.

You would want something more like this where each method works on the DuplicatedAdSlice type rather than the DuplicatedAd type.

type DuplicatedAdSlice []DuplicatedAd // Type alias

func (slice DuplicatedAdSlice) Len() int {
    return len(slice)
}

And update the CpResponse struct to use the type alias

// The Doublet Ads to show
Duplicated DuplicatedAdSlice `json:"duplicated"`

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.