--
import ( "container/list" ) type Iterator struct { e *list.Element } func (p *Iterator) Valid() bool { return p.e != nil } func (p *Iterator) Value() (int, int) { pe := p.e.Value.(*Element) return pe.k, pe.v } func (p *Iterator) Next() { p.e = p.e.Next() } type Element struct { k, v int } type ListMap struct { m map[int]*list.Element l *list.List } func NewListMap() *ListMap { return &ListMap{ m: make(map[int]*list.Element), l: list.New(), } } func (p *ListMap) Set(k, v int) { e, ok := p.m[k] if ok { e.Value.(*Element).v = v } else { p.m[k] = p.l.PushBack(&Element{k, v}) } } func (p *ListMap) Get(k int) (int, bool) { e, ok := p.m[k] if !ok { return 0, false } return e.Value.(*Element).v, true } func (p *ListMap) Delete(k int) { e, ok := p.m[k] if ok { delete(p.m, k) p.l.Remove(e) } } func (p *ListMap) Iterate() Iterator { return Iterator{p.l.Front()} }
On 31 Mar 2013 00:44, "Péter Szilágyi" <pet...@gmail.com> wrote:
>
> Hi,
>
> I was wondering whether there's any mechanism to iterate over a map that is capable of suspending the iteration and resuming it later.
>
> E.g. something along the lines:
>
> for k, v in range myMap {
> // Break for some reason
> }
>
> // Do other stuff
>
> for k, x in <somehow continue> {
> // Etc.
> }
>
Replace the "break" word with the contents of "do other stuff".
> The above code is just a wild example. A more appropriate and real world use case would be if a map is used as an internal data structure for an object/collection which would need iteration support (e.g. bag).
If my answer does not solve the problem, it means that you have given the wrong pseudo-code. Please explain what you are trying to do with more details.
Also I don't see any reason why an algorithm would make a difference between two arbitrary halves of an unordered collection, can you give an example?
Rémy.
There is no language level support for custom iterators because it would add a lot of complexity for a little syntactic sugar. Take a look at the new bufio.Scanner for an example of an idiomatic iterator that does not use range.
http://tip.golang.org/pkg/bufio/#Scanner
Andrew
The possibility to stop an iteration, do something else and then continue can also be invaluable in memoization style algorithms where you don't calculate for the whole collection something, just maybe for a small part of it. And later if it turns out to be needed, you can just continue where you left off. This is a bit more subtle, but one crude example might be a simple graph search algorithm where you're trying to find a path from a source to dest1. Afterwards it turns out that you'd also like the path to dest2. Now you either rerun a whole lot of searching, or you can just save the state of the previous search where you broke out. That's where you need iterators that can continue.
PS: Just a random counterexample to your design: iterate over two, same-length bags simultaneously.