diff --git a/iterator.go b/iterator.go new file mode 100644 index 0000000..c1a332e --- /dev/null +++ b/iterator.go @@ -0,0 +1,58 @@ +package orderedmap + +type PairsIterator struct { + m *OrderedMap + index int + length int +} + +func (it *PairsIterator) Index() int { + return it.index +} + +func (it *PairsIterator) Length() int { + return it.length +} + +func (it *PairsIterator) Next() (*Pair, error) { + index := it.index + it.index++ + key := it.m.keys[index] + return &Pair{key, it.m.values[key]}, nil +} + +func (it *PairsIterator) Done() bool { + return it.index >= it.length +} + +func (it *PairsIterator) Close() error { + return nil +} + +type ValuesIterator struct { + m *OrderedMap + index int + length int +} + +func (it *ValuesIterator) Index() int { + return it.index +} + +func (it *ValuesIterator) Length() int { + return it.length +} + +func (it *ValuesIterator) Next() (interface{}, error) { + index := it.index + it.index++ + return it.m.values[it.m.keys[index]], nil +} + +func (it *ValuesIterator) Done() bool { + return it.index >= it.length +} + +func (it *ValuesIterator) Close() error { + return nil +} diff --git a/orderedmap.go b/orderedmap.go index 7c8e6fe..50f87ae 100644 --- a/orderedmap.go +++ b/orderedmap.go @@ -8,6 +8,7 @@ import ( ) var NoValueError = errors.New("No value for this key") +var Done = errors.New("no more items in iterator") type KeyIndex struct { Key string @@ -20,7 +21,7 @@ func (a ByIndex) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByIndex) Less(i, j int) bool { return a[i].Index < a[j].Index } type Pair struct { - key string + key string value interface{} } @@ -33,7 +34,7 @@ func (kv *Pair) Value() interface{} { } type ByPair struct { - Pairs []*Pair + Pairs []*Pair LessFunc func(a *Pair, j *Pair) bool } @@ -41,6 +42,8 @@ func (a ByPair) Len() int { return len(a.Pairs) } func (a ByPair) Swap(i, j int) { a.Pairs[i], a.Pairs[j] = a.Pairs[j], a.Pairs[i] } func (a ByPair) Less(i, j int) bool { return a.LessFunc(a.Pairs[i], a.Pairs[j]) } + + type OrderedMap struct { keys []string values map[string]interface{} @@ -58,6 +61,11 @@ func (o *OrderedMap) Get(key string) (interface{}, bool) { return val, exists } +func (o *OrderedMap) Has(key string) bool { + _, exists := o.values[key] + return exists +} + func (o *OrderedMap) Set(key string, value interface{}) { _, exists := o.values[key] if !exists { @@ -106,6 +114,24 @@ func (o *OrderedMap) Sort(lessFunc func(a *Pair, b *Pair) bool) { } } +func (o *OrderedMap) EachValues(cb func(value interface{}) error) (err error) { + for i, max := 0, len(o.keys); i < max; i++ { + err = cb(o.values[o.keys[i]]) + if err != nil { + return err + } + } + return +} + +func (o *OrderedMap) IterValues() *ValuesIterator { + return &ValuesIterator{o, 0, len(o.keys)} +} + +func (o *OrderedMap) Iter() *PairsIterator { + return &PairsIterator{o, 0, len(o.keys)} +} + func (o *OrderedMap) UnmarshalJSON(b []byte) error { m := map[string]interface{}{} if err := json.Unmarshal(b, &m); err != nil {