结构体数组去重复

我有一个结构数组,我想删除所有重复元素,但保留数组中的最后一个元素。类似于 hashmap 的东西,我可以将每次匹配的最后一个结构更新为新数组


我有一个像这样的结构


type samplestruct struct {

    value1           string    

    value2           string   

    value3           string   

    value4           string

    value5           string

}

在我的结构数组中,如果任何结构的 value1、value2 和 value3 相同,则删除所有重复项并保留最后一个结构。


func unique(sample []samplestruct) []samplestruct {

    var unique []samplestruct


    for _, v := range sample {

        skip := false

        for _, u := range unique {

            if v.value1 == u.value1 && v.value2 == u.value2 && v.value3 == u.value3 {

                skip = true

                break

            }

        }

        if !skip {

            unique = append(unique, v)

        }

    }

    return unique


}

此代码返回与所提供的条件匹配的第一个结构,但我想要与条件匹配的最后一个结构


给定输入 -


[

samplestruct{"ram","rahim","india","34","india"},

samplestruct{"ram","rahim","india","38","America"},

samplestruct{"ram","rahim","india","40","Jamica"},

samplestruct{"amit","rawat","bangladesh","35","hawai"},

samplestruct{"amit","rawat","bangladesh","36","india"}

]

预期输出 -


[

samplestruct{"ram","rahim","india","40","Jamica"},

samplestruct{"amit","rawat","bangladesh","36","india"}

]


侃侃尔雅
浏览 108回答 4
4回答

米琪卡哇伊

问题中的代码已经差不多了。当在 中找到匹配元素时unique,用当前值覆盖该元素:func unique(sample []samplestruct) []samplestruct {    var unique []samplestructsampleLoop:    for _, v := range sample {        for i, u := range unique {            if v.value1 == u.value1 && v.value2 == u.value2 && v.value3 == u.value3 {                unique[i] = v                continue sampleLoop            }        }        unique = append(unique, v)    }    return unique}其他答案中显示的基于地图的方法可能更合适,具体取决于数据集的大小和幸存元素的数量。这是地图方法的正确实现:func unique(sample []samplestruct) []samplestruct {    var unique []samplestruct    type key struct{ value1, value2, value3 string }    m := make(map[key]int)    for _, v := range sample {        k := key{v.value1, v.value2, v.value3}        if i, ok := m[k]; ok {            // Overwrite previous value per requirement in            // question to keep last matching value.            unique[i] = v        } else {            // Unique key found. Record position and collect            // in result.            m[k] = len(unique)            unique = append(unique, v)        }    }    return unique}

临摹微笑

很好的小练习,这是一个解决方案,我将在下面解释:package mainimport "fmt"func main() {    all := []person{        {"ram", "rahim", "india", "34", "india"},        {"ram", "rahim", "india", "38", "America"},        {"ram", "rahim", "india", "40", "Jamica"},        {"amit", "rawat", "bangladesh", "35", "hawai"},        {"amit", "rawat", "bangladesh", "36", "india"},    }    var deduped []person    // add the last occurrence always    for i := len(all) - 1; i >= 0; i-- {        if !contains(deduped, all[i]) {            // "append" to the front of the array            deduped = append([]person{all[i]}, deduped...)        }    }    for _, x := range deduped {        fmt.Println(x)    }}type person [5]stringfunc eq(a, b person) bool {    return a[0] == b[0] && a[1] == b[1] && a[2] == b[2]}func contains(list []person, x person) bool {    for i := range list {        if eq(x, list[i]) {            return true        }    }    return false}我们向后遍历输入数组,以捕获多个相等项中的最后一个。然后我们想将该项目附加到数组的后面deduped。这就是为什么我们恢复追加操作,创建一个新的临时单项person切片并将前一个切片附加到其中。从效率角度来看,该解决方案有一些缺点,附加到单项切片将使用 O(n²) 空间,因为它每次都会生成一个新切片,预先分配一个 数组,附加到它,然后反转它可以len(all)解决那个问题。如果您对无数次执行此操作,可能会出现的第二个性能问题person是contains程序的 O(n²) 查找函数。这可以通过map[person]bool.

汪汪一只猫

也许你应该在这里使用一个映射,使用重要的值作为键,当你遇到重复并检查键时,你替换映射中的值。unique目前,如果您之前没有遇到过这些值,则将其添加到数组中,然后如果您在数组中遇到该值,则跳过它。这就是为什么您只添加每个结构的第一次遇到,这与您想要的相反。您可以将映射的键生成为重要值(1 到 3)的串联,或者使用三个值的结构作为键,并为每个项目构建新的键结构,然后在地图。使用映射也比数组具有更高的性能,因为在映射中查找比unique每次迭代数组要快得多。

蛊毒传说

使用地图。首先扫描列表并设置一个映射,其中前 3 个值作为映射的键。每个键的映射值将是最后找到的然后在地图上行走,它将被设置为正确的值package mainimport (    "fmt"    "strings")type samplestruct struct {    value1 string    value2 string    value3 string    value4 string    value5 string}func mkey(x samplestruct) string {    return strings.Join([]string{x.value1, x.value2, x.value3}, "-")}func main() {    cm := make(map[string]samplestruct)    exampledata := []samplestruct{samplestruct{"ram", "rahim", "india", "34", "india"},        samplestruct{"ram", "rahim", "india", "38", "America"},        samplestruct{"ram", "rahim", "india", "40", "Jamica"},        samplestruct{"amit", "rawat", "bangladesh", "35", "hawai"},        samplestruct{"amit", "rawat", "bangladesh", "36", "india"}}    for _, x := range exampledata {        k := mkey(x)        cm[k] = x    }    for x := range cm {        fmt.Println(cm[x])    }}https://play.golang.org/p/ITD0VjhFQEk
打开App,查看更多内容
随时随地看视频慕课网APP