如何从切片中删除项目的重复项?

时间:2014-10-03 02:58:47

标签: go

我正在编写一个命令行工具,它将从文本文件中删除对等项。

这是文本文件。它在代码中的引用是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和地址创建对等对象。看起来像这样

peer := config.BootstrapPeer{
                Address: address,
                PeerID:  pID,
            }

目标是删除包含用户提供的地址和PeerID的所有对等cfg.Bootstrap

   //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)

    }

这适用于cfg.Bootstrap中的最后一个对等项有重复。如果它有重复,那么Go恐慌与

panic: runtime error: slice bounds out of range

我需要这样做,以便用户可以删除包含最后一个对等体的对等体的所有副本。有什么想法吗?

2 个答案:

答案 0 :(得分:8)

基本思想是将值!=复制到切片的开头,并在完成时修剪多余的部分。

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]

答案 1 :(得分: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
}