英文:
How to delete duplicates of an item from a slice?
问题
我正在编写一个命令行工具,用于从文本文件中删除对等体。
这是文本文件。在代码中的引用是cfg.Bootstrap。
"Bootstrap": [
{
"Address": "/ip4/162.243.139.64/tcp/5001",
"PeerID": "QmXZPT1SLcczjNSLnSCsQBWwbosKjrDRo122Ys8ajKoQXQ"
},
{
"Address": "/ip4/162.243.139.64/tcp/5001",
"PeerID": "QmXZPT1SLcczjNSLnSCsQBWwbosKjrDRo122Ys8ajKoQXA"
},
{
"Address": "/ip4/162.243.139.64/tcp/5001",
"PeerID": "QmXZPT1SLcczjNSLnSCsQBWwbosKjrDRo122Ys8ajKoQXQ"
},
{
"Address": "/ip4/162.243.139.64/tcp/5001",
"PeerID": "QmXZPT1SLcczjNSLnSCsQBWwbosKjrDRo122Ys8ajKoQXA"
}
]
使用用户提供的PeerID和Address创建对等体对象,如下所示:
peer := config.BootstrapPeer{
Address: address,
PeerID: pID,
}
目标是删除所有包含用户提供的Address和PeerID的cfg.Bootstrap中的对等体。
//多次迭代对等体列表,以便删除所有匹配项
for i := range cfg.Bootstrap {
//迭代对等体列表
for i, val := range cfg.Bootstrap {
//如果用户提供的PeerID和Address与cfg.Bootstrap中的对等体对象匹配..
if(val.PeerID == peer.PeerID && val.Address == peer.Address) {
//删除该元素
cfg.Bootstrap = append(cfg.Bootstrap[:i], cfg.Bootstrap[i+1:]...)
}
}
fmt.Println(i)
}
这个方法是有效的,除非cfg.Bootstrap中的最后一个对等体有一个重复项。如果有重复项,Go会出现错误:
panic: runtime error: slice bounds out of range
我需要让用户能够删除包含最后一个对等体的所有副本。有什么想法吗?
英文:
I'm writing a command line tool that will delete peers from a text file.
This is the text file. Its reference in code is cfg.Bootstrap
"Bootstrap": [
{
"Address": "/ip4/162.243.139.64/tcp/5001",
"PeerID": "QmXZPT1SLcczjNSLnSCsQBWwbosKjrDRo122Ys8ajKoQXQ"
},
{
"Address": "/ip4/162.243.139.64/tcp/5001",
"PeerID": "QmXZPT1SLcczjNSLnSCsQBWwbosKjrDRo122Ys8ajKoQXA"
},
{
"Address": "/ip4/162.243.139.64/tcp/5001",
"PeerID": "QmXZPT1SLcczjNSLnSCsQBWwbosKjrDRo122Ys8ajKoQXQ"
},
{
"Address": "/ip4/162.243.139.64/tcp/5001",
"PeerID": "QmXZPT1SLcczjNSLnSCsQBWwbosKjrDRo122Ys8ajKoQXA"
}
]
The peer object is created using a user supplied PeerID and Address. It looks like this
peer := config.BootstrapPeer{
Address: address,
PeerID: pID,
}
The goal is to remove all peers cfg.Bootstrap that contain the user supplied Address and PeerID
//iterate through the list of peers multiple times so that we delete all matches
for i := range cfg.Bootstrap {
//iterate through the list of peers
for i, val := range cfg.Bootstrap {
//if the user supplied PeerID and Address match a Peer object in cfg.Bootstrap..
if(val.PeerID == peer.PeerID && val.Address == peer.Address) {
//remove that element
cfg.Bootstrap = append(cfg.Bootstrap[:i], cfg.Bootstrap[i+1:]...)
}
}
fmt.Println(i)
}
This works UNLESS the last peer in cfg.Bootstrap has a duplicate. If it has a duplicate then Go panics with
panic: runtime error: slice bounds out of range
I need to make it so the user can delete all copies of a peer that include the last peer. Any ideas?
答案1
得分: 9
基本思想是将不等于对等方的值复制到切片的开头,并在完成后修剪多余的部分。
i := 0
for _, v := range cfg.Bootstrap {
if v.PeerId == peer.PeerId && v.Address == peer.Address {
continue
}
cfg.Bootstrap[i] = v
i++
}
cfg.Bootstrap = cfg.Bootstrap[:i]
英文:
The basic idea is to copy values != to peer to the beginning of the slice and trim the excess when done.
i := 0
for _, v := range cfg.Bootstrap {
if v.PeerId == peer.PeerId && v.Address == peer.Address {
continue
}
cfg.Bootstrap[i] = v
i++
}
cfg.Bootstrap = cfg.Bootstrap[:i]
答案2
得分: 0
另一种方法(如果你有这个选项)是先排序,然后去除重复项。例如,对于字符串:
strs = []string{"a", "b", "c", "d", "e", "b", "a", "e", "e", "d"}
sort.Strings(strs)
var last string
first_item := true
dedupped := []string{}
for _, s := range strs {
if first_item {
dedupped = append(dedupped, s)
first_item = false
} else {
if s != last {
dedupped = append(dedupped, s)
}
}
last = s
}
另一种方法(如果您有此选项)是先对字符串进行排序,然后删除重复项。例如:
strs = []string{"a", "b", "c", "d", "e", "b", "a", "e", "e", "d"}
sort.Strings(strs)
var last string
first_item := true
dedupped := []string{}
for _, s := range strs {
if first_item {
dedupped = append(dedupped, s)
first_item = false
} else {
if s != last {
dedupped = append(dedupped, s)
}
}
last = s
}
英文:
Another approach (if you have the option) is to first sort, then remove duplicates. Eg with strings;
strs = []string{"a", "b", "c", "d", "e", "b", "a", "e", "e", "d"}
sort.Strings(strs)
var last string
first_item := true
dedupped := []string{}
for _, s := range strs {
if first_item {
dedupped = append(dedupped, s)
first_item = false
} else {
if s != last {
dedupped = append(dedupped, s)
}
}
last = s
}
答案3
得分: 0
将你的结构体编组成 JSON,然后将其转换为字符串。
data, _ := json.Marshal(yourStruct)
dup := make(map[string]bool)
dup[string(data)] = true
现在可以使用这个 dup
来过滤掉重复项。
英文:
Marshal your struct into json and then stringify
data, _ := json.Marshal(yourStruct)
dup := make(map[string]bool)
dup[string(data)] = true
Now use this dup to filter out duplicates
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论