Reputation: 43
I'm trying to sort a collection of structs by the order of another strings characters with the same values.
Here's an example:
package main
import (
"fmt"
"sort"
"strings"
)
type Container struct {
Initial string
}
func main() {
s := "dfah"
c := []Container{}
for _, r := range "fadh" {
c = append(c, Container{Initial: string(r)})
}
sort.Slice(c, func(i, j int) bool {
str := strings.Compare(c[i].Initial, s)
if str == -1 {
return true
} else {
return false
}
})
fmt.Printf("Result: %s\n", c) // returns 'dafh'
fmt.Printf("Desired result: %s\n", s) // returns 'dfah'
}
The desired result would be the sorted collection of Container
structs, with the same order of the 'dfah' string.
https://play.golang.org/p/eDW5-xpCzv
They will always have the same characters/number of characters, just unsorted. I'm not sure what the correct way to accomplish this is. Any ideas? Thanks!
Upvotes: 0
Views: 394
Reputation: 58369
In your slice-sorting function, you're comparing c[i].Initial
to s
. That's simply wrong. Instead, you want to find whether c[i].Initial
appears in s
before or after c[j].Initial
.
Here's some example code, or see it running on the playground:
package main
import (
"fmt"
"sort"
"strings"
)
type Container struct {
Initial string
}
func main() {
s := "dfah"
c := []Container{}
for _, r := range "fadh" {
c = append(c, Container{Initial: string(r)})
}
sort.Slice(c, func(i, j int) bool {
return strings.Index(s, c[i].Initial) <= strings.Index(s, c[j].Initial)
})
fmt.Printf("Result: %s\n", c) // returns [{d} {f} {a} {h}]
fmt.Printf("Desired result: %s\n", s) // returns 'dfah'
}
Note in practice, this is inefficient, since it involves scanning s
lots of times. If this were real code, I'd be building a map from characters of s
to their index so that the strings.Index
calls could be replaced by map lookups.
Upvotes: 1