Idiomatic go way to compare 2 slices to see which element has been removed -


i using rethinkdb in application , have lobby has users.

rethinkdb has ability watch changes table , when changes happen automagically emits changes can whatever want data, right i'm trying make when user leaves lobby can send websocket out remove user. thing i'm trying find out difference in before / after data slice of members, data:

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"` } 

right i'm doing

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)         res.next(&changes) {             if changes.newval != nil && changes.oldval != nil {                 switch {                 case len(changes.newval.members) > len(changes.oldval.members):                     // member has joined announce was.                  case len(changes.newval.members) < len(changes.oldval.members):                     // member has left announce was.            -------->                 case len(changes.newval.messages) > len(changes.oldval.messages):                     // new message recieved announce message.                  }             }         }     }(res, l)      select {     case <-l.killme:         res.close()         break     } } 

the new entries easy enough i'll take end off slice , send that, when comes user leaving, how can compare changes.newval.members , changes.oldval.members see index removed can send right member remove through websocket. hope question clear let me know if isn't.

this how i'm doing it

removedindex := 0 i, oldmember := range changes.oldval.members {     foundmissing := true     _, newmember := range changes.newval.members {         if reflect.deepequal(oldmember, newmember) {             foundmissing = false         }     }     if foundmissing {         removedindex =         break     } } 

but feels bit hacky, there better way?

sort old , new members unique , sortable key. looks steamid might suitable purpose. iterate through both slices checking added , deleted elements comparing keys.

func diff(old []*member, new []*member) {   sort.sort(bysteamid(old))   sort.sort(bysteamid(new))   i, j := 0, 0   < len(old) && j < len(new) {     switch {     case old[i].steamid < new[j].steamid:         fmt.println(" delete", old[i].steamid)         i++     case old[i].steamid > new[j].steamid:         fmt.println(" add", new[j].steamid)         j++     default:         i++         j++     }   }   < len(old) {     fmt.println(" delete", old[i].steamid)     i++   }   j < len(new) {     fmt.println(" add", new[j].steamid)     j++   } } 

playground example


Comments

Popular posts from this blog

how to insert data php javascript mysql with multiple array session 2 -

multithreading - Exception in Application constructor -

windows - CertCreateCertificateContext returns CRYPT_E_ASN1_BADTAG / 8009310b -