@@ -42,9 +42,16 @@ class SparseIntArray:
4242 result
4343 }
4444
45+ /** All defined indices in an iterator */
46+ def keysIterator : Iterator [Int ] = root.keysIterator(0 )
47+
48+ /** Perform operation for each key/value pair */
4549 def foreachBinding (op : (Int , Value ) => Unit ): Unit =
4650 root.foreachBinding(op, 0 )
4751
52+ /** Transform each defined value with transformation `op`.
53+ * The transformation gets the element index and value as parameters.
54+ */
4855 def transform (op : (Int , Value ) => Value ): Unit =
4956 root.transform(op, 0 )
5057
@@ -82,6 +89,7 @@ object SparseIntArray:
8289 def update (index : Int , value : Value ): Boolean
8390 def remove (index : Int ): Boolean
8491 def isEmpty : Boolean
92+ def keysIterator (offset : Int ): Iterator [Int ]
8593 def foreachBinding (op : (Int , Value ) => Unit , offset : Int ): Unit
8694 def transform (op : (Int , Value ) => Value , offset : Int ): Unit
8795 def nodeCount : Int
@@ -111,6 +119,17 @@ object SparseIntArray:
111119
112120 def isEmpty = present == 0
113121
122+ private def skipUndefined (i : Int ): Int =
123+ if i < NodeSize && ! contains(i) then skipUndefined(i + 1 ) else i
124+
125+ def keysIterator (offset : Int ) = new Iterator [Int ]:
126+ private var curIdx = skipUndefined(0 )
127+ def hasNext = curIdx < NodeSize
128+ def next (): Int =
129+ val result = curIdx + offset
130+ curIdx = skipUndefined(curIdx + 1 )
131+ result
132+
114133 def foreachBinding (op : (Int , Value ) => Unit , offset : Int ): Unit =
115134 var i = 0
116135 while i < NodeSize do
@@ -167,6 +186,20 @@ object SparseIntArray:
167186
168187 def isEmpty = empty
169188
189+ private def skipUndefined (i : Int ): Int =
190+ if i < NodeSize && elems(i) == null then skipUndefined(i + 1 ) else i
191+
192+ def keysIterator (offset : Int ) = new Iterator [Value ]:
193+ private var curIdx = skipUndefined(0 )
194+ private var elemIt = Iterator .empty[Int ]
195+ def hasNext = elemIt.hasNext || curIdx < NodeSize
196+ def next (): Value =
197+ if elemIt.hasNext then elemIt.next()
198+ else
199+ elemIt = elems(curIdx).keysIterator(offset + curIdx * elemSize)
200+ curIdx = skipUndefined(curIdx + 1 )
201+ elemIt.next()
202+
170203 def foreachBinding (op : (Int , Value ) => Unit , offset : Int ): Unit =
171204 var i = 0
172205 while i < NodeSize do
@@ -205,6 +238,7 @@ end SparseIntArray
205238 println(s " a = $a" )
206239 a(55555 ) = 44
207240 println(s " a = $a" )
241+ println(s " iterator of a yields ${a.keysIterator.toList}" )
208242 assert(a.size == 3 , a)
209243 assert(a.contains(1 ), a)
210244 assert(a.contains(222 ), a)
0 commit comments