Last active
September 21, 2018 11:23
-
-
Save narqo/0908ccd333364a065606024fb4b5e568 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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