按相同值的字符串顺序对结构进行排序

huangapple go评论72阅读模式
英文:

Sort struct by order of string with same values

问题

我正在尝试按照另一个字符串的字符顺序对一组结构体进行排序,这些结构体具有相同的值。

这是一个示例:

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) // 返回 'dafh'
    fmt.Printf("Desired result: %s\n", s) // 返回 'dfah'
}

期望的结果是按照字符串 'dfah' 的顺序对 Container 结构体进行排序。

它们始终具有相同的字符/字符数量,只是未排序。我不确定实现这一目标的正确方法是什么。有什么想法吗?谢谢!

英文:

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!

答案1

得分: 1

在你的切片排序函数中,你将c[i].Initials进行比较。这是错误的。相反,你想要找出c[i].Initials中是在c[j].Initial之前还是之后。

以下是一些示例代码,或者你可以在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)         // 返回 [{d} {f} {a} {h}]
	fmt.Printf("Desired result: %s\n", s) // 返回 'dfah'
}

请注意,在实际应用中,这种方法效率低下,因为它需要多次扫描s。如果这是真实的代码,我会构建一个从s的字符到它们的索引的映射,这样就可以用映射查找来替代strings.Index调用。

英文:

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 (
	&quot;fmt&quot;
	&quot;sort&quot;
	&quot;strings&quot;
)

type Container struct {
	Initial string
}

func main() {
	s := &quot;dfah&quot;
	c := []Container{}

	for _, r := range &quot;fadh&quot; {
		c = append(c, Container{Initial: string(r)})
	}

	sort.Slice(c, func(i, j int) bool {
		return strings.Index(s, c[i].Initial) &lt;= strings.Index(s, c[j].Initial)
	})

	fmt.Printf(&quot;Result: %s\n&quot;, c)         // returns [{d} {f} {a} {h}]
	fmt.Printf(&quot;Desired result: %s\n&quot;, s) // returns &#39;dfah&#39;
}

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.

huangapple
  • 本文由 发表于 2017年9月17日 14:03:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/46261204.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定