4 回答

TA貢獻(xiàn)1998條經(jīng)驗(yàn) 獲得超6個(gè)贊
問(wèn)題中的代碼已經(jīng)差不多了。當(dāng)在 中找到匹配元素時(shí)unique,用當(dāng)前值覆蓋該元素:
func unique(sample []samplestruct) []samplestruct {
var unique []samplestruct
sampleLoop:
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
}
其他答案中顯示的基于地圖的方法可能更合適,具體取決于數(shù)據(jù)集的大小和幸存元素的數(shù)量。這是地圖方法的正確實(shí)現(xiàn):
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
}

TA貢獻(xiàn)1982條經(jīng)驗(yàn) 獲得超2個(gè)贊
很好的小練習(xí),這是一個(gè)解決方案,我將在下面解釋?zhuān)?/p>
package main
import "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]string
func 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
}
我們向后遍歷輸入數(shù)組,以捕獲多個(gè)相等項(xiàng)中的最后一個(gè)。然后我們想將該項(xiàng)目附加到數(shù)組的后面deduped。這就是為什么我們恢復(fù)追加操作,創(chuàng)建一個(gè)新的臨時(shí)單項(xiàng)person切片并將前一個(gè)切片附加到其中。
從效率角度來(lái)看,該解決方案有一些缺點(diǎn),附加到單項(xiàng)切片將使用 O(n2) 空間,因?yàn)樗看味紩?huì)生成一個(gè)新切片,預(yù)先分配一個(gè) 數(shù)組,附加到它,然后反轉(zhuǎn)它可以len(all)解決那個(gè)問(wèn)題。
如果您對(duì)無(wú)數(shù)次執(zhí)行此操作,可能會(huì)出現(xiàn)的第二個(gè)性能問(wèn)題person是contains程序的 O(n2) 查找函數(shù)。這可以通過(guò)map[person]bool.

TA貢獻(xiàn)1898條經(jīng)驗(yàn) 獲得超8個(gè)贊
也許你應(yīng)該在這里使用一個(gè)映射,使用重要的值作為鍵,當(dāng)你遇到重復(fù)并檢查鍵時(shí),你替換映射中的值。
unique
目前,如果您之前沒(méi)有遇到過(guò)這些值,則將其添加到數(shù)組中,然后如果您在數(shù)組中遇到該值,則跳過(guò)它。這就是為什么您只添加每個(gè)結(jié)構(gòu)的第一次遇到,這與您想要的相反。
您可以將映射的鍵生成為重要值(1 到 3)的串聯(lián),或者使用三個(gè)值的結(jié)構(gòu)作為鍵,并為每個(gè)項(xiàng)目構(gòu)建新的鍵結(jié)構(gòu),然后在地圖。
使用映射也比數(shù)組具有更高的性能,因?yàn)樵谟成渲胁檎冶?code>unique每次迭代數(shù)組要快得多。

TA貢獻(xiàn)1895條經(jīng)驗(yàn) 獲得超3個(gè)贊
使用地圖。首先掃描列表并設(shè)置一個(gè)映射,其中前 3 個(gè)值作為映射的鍵。每個(gè)鍵的映射值將是最后找到的
然后在地圖上行走,它將被設(shè)置為正確的值
package main
import (
"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
- 4 回答
- 0 關(guān)注
- 254 瀏覽
添加回答
舉報(bào)