@@ -162,16 +162,29 @@ object Decorators {
162
162
* `xs` to themselves.
163
163
*/
164
164
def mapWithIndexConserve [U <: T ](f : (T , Int ) => U ): List [U ] =
165
- def recur (xs : List [T ], idx : Int ): List [U ] =
166
- if xs.isEmpty then Nil
167
- else
168
- val x1 = f(xs.head, idx)
169
- val xs1 = recur(xs.tail, idx + 1 )
170
- if (x1.asInstanceOf [AnyRef ] eq xs.head.asInstanceOf [AnyRef ])
171
- && (xs1 eq xs.tail)
172
- then xs.asInstanceOf [List [U ]]
173
- else x1 :: xs1
174
- recur(xs, 0 )
165
+
166
+ @ tailrec
167
+ def addAll (buf : ListBuffer [T ], from : List [T ], until : List [T ]): ListBuffer [T ] =
168
+ if from eq until then buf else addAll(buf += from.head, from.tail, until)
169
+
170
+ @ tailrec
171
+ def loopWithBuffer (buf : ListBuffer [U ], explore : List [T ], idx : Int ): List [U ] = explore match
172
+ case Nil => buf.toList
173
+ case t :: rest => loopWithBuffer(buf += f(t, idx), rest, idx + 1 )
174
+
175
+ @ tailrec
176
+ def loop (keep : List [T ], explore : List [T ], idx : Int ): List [U ] = explore match
177
+ case Nil => keep.asInstanceOf [List [U ]]
178
+ case t :: rest =>
179
+ val u = f(t, idx)
180
+ if u.asInstanceOf [AnyRef ] eq t.asInstanceOf [AnyRef ] then
181
+ loop(keep, rest, idx + 1 )
182
+ else
183
+ val buf = addAll(new ListBuffer [T ], keep, explore).asInstanceOf [ListBuffer [U ]]
184
+ loopWithBuffer(buf += u, rest, idx + 1 )
185
+
186
+ loop(xs, xs, 0 )
187
+ end mapWithIndexConserve
175
188
176
189
final def hasSameLengthAs [U ](ys : List [U ]): Boolean = {
177
190
@ tailrec def loop (xs : List [T ], ys : List [U ]): Boolean =
@@ -278,4 +291,3 @@ object Decorators {
278
291
def binarySearch (x : T ): Int = java.util.Arrays .binarySearch(arr.asInstanceOf [Array [Object ]], x)
279
292
280
293
}
281
-
0 commit comments