Skip to content

Instantly share code, notes, and snippets.

@narqo
Last active September 21, 2018 11:23
Show Gist options
  • Save narqo/0908ccd333364a065606024fb4b5e568 to your computer and use it in GitHub Desktop.
Save narqo/0908ccd333364a065606024fb4b5e568 to your computer and use it in GitHub Desktop.
package id
type IdType int
const (
IdTypeUnknown IdType = -1
IdType1 IdType = iota
IdType2
)
type Id struct {
string
// pointer to next element in the chain of ids
nextId *Id
}
var ZeroId = Id{}
// NewId is a test helper for creating a chain of ids.
func NewId(values ...string) (id Id) {
if len(values) == 0 {
return ZeroId
}
// push front values, so Next iterated over them in the original order
for i := len(values) - 1; i >= 0; i-- {
nextId := id
id = Id{string: values[i]}
if nextId != ZeroId {
id.nextId = &nextId
}
}
return id
}
func (id Id) Next() (nextId Id, ok bool) {
if id.nextId == nil {
return ZeroId, false
}
return *id.nextId, true
}
func (id Id) String() string {
if id.nextId == nil {
return id.string
}
s := strings.Builder{}
s.WriteString(id.string)
for nextId := id.nextId; nextId != nil; nextId = nextId.nextId {
s.WriteByte(',')
s.WriteString(nextId.string)
}
return s.String()
}
func (id Id) Value() string {
return id.string
}
func (id Id) Values() (values []string) {
if id.string == "" {
return nil
}
values = append(values, id.string)
for nextId := id.nextId; nextId != nil; nextId = nextId.nextId {
values = append(values, nextId.string)
}
return values
}
// Ids is the collection of several hashes device IDs obtained from a request.
type Ids map[IdType]Id
type idsIterator struct {
ids Ids
keys []IdType
n int
idType IdType
id Id
}
func newIdsIterator(ids Ids) *idsIterator {
it := &idsIterator{
keys: make([]IdType, 0, len(ids)),
}
it.Reset(ids)
return it
}
func (it *idsIterator) Reset(ids Ids) {
it.ids = ids
it.keys = it.keys[:0]
it.n = 0
it.idType = IdTypeUnknown
it.id = ZeroId
}
func (it *idsIterator) lazyInit() {
if len(it.keys) != 0 {
return
}
for idType := range it.ids {
it.keys = append(it.keys, idType)
}
}
func (it *idsIterator) Next() bool {
it.lazyInit()
if it.n >= len(it.keys) {
return false
}
if id, ok := it.id.Next(); ok {
it.id = id
return true
}
it.idType = it.keys[it.n]
it.id = it.ids[it.idType]
it.n++
return true
}
func (it *idsIterator) Id() (IdType, Id) {
return it.idType, it.id
}
func ExampleIds() {
ids := Ids{
IdType1: NewId("id1val1", "id1val2", "id1val3"),
IdType2: NewId("id2val1"),
}
it := newIdsIterator(ids)
for it.Next() {
idType, id := it.Id()
// do something
_, _ = idType, id
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment