猿问

比较 2 个切片以查看哪个元素已被删除的惯用方法

我在我的应用程序中使用RethinkDB,我有一个有用户的大厅。


RethinkDB 能够监视表的更改,当发生更改时,它会自动发出更改,以便您可以对数据做任何想做的事情,现在我正在尝试这样做,以便当用户离开大厅时我可以发送一个用于删除用户的 websocket。唯一的事情是我试图找出之前/之后数据的不同之处,这是一个切片members,这是数据:


type change struct {

    NewVal *fields `gorethink:"new_val,omitempty"`

    OldVal *fields `gorethink:"old_val,omitempty"`

}


type fields struct {

    ID      string `gorethink:"id"`

    Owner   string `gorethink:"owner"`

    Inqueue bool   `gorethink:"inqueue"`

    Members []struct {

        SteamID  string `gorethink:"steamid"`

        Username string `gorethink:"username"`

    } `gorethink:"members"`

    Messages []struct {

        Username  string    `gorethink:"username"`

        Message   string    `gorethink:"message"`

        CreatedAt time.Time `gorethink:"createdAt"`

    } `gorethink:"messages"`

}

现在我在做


func (l *lobby) watchChanges() {

    db := common.DB()

    query := gorethink.Table("Lobbys").Get(l.ID).Changes()

    res, err := query.Run(db)

    if err != nil {

        log.Println(err)

    }


    go func(res *gorethink.Cursor, l *lobby) {

        defer res.Close()

        changes := new(change)

        for res.Next(&changes) {

            if changes.NewVal != nil && changes.OldVal != nil {

                switch {

                case len(changes.NewVal.Members) > len(changes.OldVal.Members):

                    // Member has joined so announce who it was.


                case len(changes.NewVal.Members) < len(changes.OldVal.Members):

                    // Member has left so announce who it was.

           -------->

                case len(changes.NewVal.Messages) > len(changes.OldVal.Messages):

                    // New Message was recieved so announce the message.


                }

            }

        }

    }(res, l)


    select {

    case <-l.KillMe:

        res.Close()

        break

    }

}

新条目很简单,我只是将切片的末尾取下并发送,但是当涉及到用户离开时,我如何比较changes.NewVal.Members和changes.OldVal.Members查看删除了哪个索引,以便我可以发送正确的成员来删除通过网络套接字。希望我的问题很清楚,如果不是,请告诉我。


但感觉有点hacky,有没有更好的方法?


翻翻过去那场雪
浏览 180回答 1
1回答

千万里不及你

按唯一且可排序的键对旧成员和新成员进行排序。看起来 SteamID 可能适合此目的。通过比较键,遍历两个切片检查添加和删除的元素。func diff(old []*member, new []*member) {&nbsp; sort.Sort(bySteamID(old))&nbsp; sort.Sort(bySteamID(new))&nbsp; i, j := 0, 0&nbsp; for i < len(old) && j < len(new) {&nbsp; &nbsp; switch {&nbsp; &nbsp; case old[i].SteamID < new[j].SteamID:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(" delete", old[i].SteamID)&nbsp; &nbsp; &nbsp; &nbsp; i++&nbsp; &nbsp; case old[i].SteamID > new[j].SteamID:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(" add", new[j].SteamID)&nbsp; &nbsp; &nbsp; &nbsp; j++&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; i++&nbsp; &nbsp; &nbsp; &nbsp; j++&nbsp; &nbsp; }&nbsp; }&nbsp; for i < len(old) {&nbsp; &nbsp; fmt.Println(" delete", old[i].SteamID)&nbsp; &nbsp; i++&nbsp; }&nbsp; for j < len(new) {&nbsp; &nbsp; fmt.Println(" add", new[j].SteamID)&nbsp; &nbsp; j++&nbsp; }}playground example
随时随地看视频慕课网APP

相关分类

Go
我要回答