@@ -162,16 +162,29 @@ object Decorators {
162162 * `xs` to themselves.
163163 */
164164 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
175188
176189 final def hasSameLengthAs [U ](ys : List [U ]): Boolean = {
177190 @ tailrec def loop (xs : List [T ], ys : List [U ]): Boolean =
@@ -278,4 +291,3 @@ object Decorators {
278291 def binarySearch (x : T ): Int = java.util.Arrays .binarySearch(arr.asInstanceOf [Array [Object ]], x)
279292
280293}
281-
0 commit comments