Skip to content

Commit a336708

Browse files
authored
Merge pull request scala#6793 from kamilkloch/seq-sort-in-place
Add `sortInPlace` to `collection.mutable.IndexedSeq`.
2 parents c29d83d + cd7f221 commit a336708

File tree

6 files changed

+88
-1
lines changed

6 files changed

+88
-1
lines changed

src/library/scala/collection/mutable/ArrayBuffer.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,17 @@ class ArrayBuffer[A] private (initElems: Array[AnyRef], initSize: Int)
159159
if(l > 0) Array.copy(array, 0, xs, start, l)
160160
xs
161161
}
162+
163+
/** Sorts this $coll in place according to an Ordering.
164+
*
165+
* @see [[scala.collection.mutable.IndexedSeqOps.sortInPlace]]
166+
* @param ord the ordering to be used to compare elements.
167+
* @return modified input $coll sorted according to the ordering `ord`.
168+
*/
169+
override def sortInPlace[B >: A]()(implicit ord: Ordering[B]): this.type = {
170+
if (length > 1) scala.util.Sorting.stableSort(array.asInstanceOf[Array[B]])
171+
this
172+
}
162173
}
163174

164175
/**

src/library/scala/collection/mutable/ArraySeq.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ abstract class ArraySeq[T]
7676
case _ =>
7777
super.equals(other)
7878
}
79+
80+
override def sortInPlace[B >: T]()(implicit ord: Ordering[B]): this.type = {
81+
if (length > 1) scala.util.Sorting.stableSort(array.asInstanceOf[Array[B]])
82+
this
83+
}
7984
}
8085

8186
/** A companion object used to create instances of `ArraySeq`.

src/library/scala/collection/mutable/IndexedSeq.scala

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,44 @@ object IndexedSeq extends SeqFactory.Delegate[IndexedSeq](ArrayBuffer)
1515

1616
trait IndexedSeqOps[A, +CC[_], +C <: AnyRef]
1717
extends scala.collection.IndexedSeqOps[A, CC, C]
18-
with SeqOps[A, CC, C]
18+
with SeqOps[A, CC, C] {
19+
20+
/** Sorts this $coll in place according to an Ordering.
21+
*
22+
* @see [[scala.collection.SeqOps.sorted]]
23+
* @param ord the ordering to be used to compare elements.
24+
* @return modified input $coll sorted according to the ordering `ord`.
25+
*/
26+
def sortInPlace[B >: A]()(implicit ord: Ordering[B]): this.type = {
27+
val len = this.length
28+
if (len > 1) {
29+
val arr = new Array[AnyRef](len)
30+
var i = 0
31+
for (x <- this) {
32+
arr(i) = x.asInstanceOf[AnyRef]
33+
i += 1
34+
}
35+
java.util.Arrays.sort(arr, ord.asInstanceOf[Ordering[Object]])
36+
i = 0
37+
while (i < arr.length) {
38+
update(i, arr(i).asInstanceOf[A])
39+
i += 1
40+
}
41+
}
42+
this
43+
}
44+
45+
/** Sorts this $coll in place according to a comparison function.
46+
*
47+
* @see [[scala.collection.SeqOps.sortWith]]
48+
*/
49+
def sortInPlaceWith(lt: (A, A) => Boolean): this.type = sortInPlace()(Ordering.fromLessThan(lt))
50+
51+
/** Sorts this $coll in place according to the Ordering which results from transforming
52+
* an implicitly given Ordering with a transformation function.
53+
*
54+
* @see [[scala.collection.SeqOps.sortBy]]
55+
*/
56+
def sortInPlaceBy[B](f: A => B)(implicit ord: Ordering[B]): this.type = sortInPlace()(ord on f)
57+
58+
}

test/junit/scala/collection/mutable/ArrayBufferTest.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,4 +289,12 @@ class ArrayBufferTest {
289289

290290
assertEquals(0, buffer.size)
291291
}
292+
293+
@Test
294+
def testSortInPlace: Unit = {
295+
val buffer = ArrayBuffer(3, 2, 1)
296+
buffer.sortInPlace()
297+
298+
assertEquals(ArrayBuffer(1, 2, 3), buffer)
299+
}
292300
}

test/junit/scala/collection/mutable/ArraySeqTest.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,20 @@ class ArraySeqTest {
2525
a.toArray.update(0, 100)
2626
assertEquals(a, List(1,2,3))
2727
}
28+
29+
@Test
30+
def testSortInPlaceAnyRef: Unit = {
31+
val arr = ArraySeq[Integer](3, 2, 1)
32+
arr.sortInPlace()
33+
assertEquals(ArraySeq[Integer](1, 2, 3), arr)
34+
}
35+
36+
@Test
37+
def testSortInPlaceInt: Unit = {
38+
val arr = ArraySeq.make(Array[Int](3, 2, 1))
39+
arr.sortInPlace()
40+
assertEquals(ArraySeq.make(Array[Int](1, 2, 3)), arr)
41+
}
2842
}
2943

3044
/*

test/junit/scala/collection/mutable/ArraySortingTest.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package scala.collection.mutable
33
import org.junit.runner.RunWith
44
import org.junit.runners.JUnit4
55
import org.junit.Test
6+
import org.junit.Assert.assertEquals
67

78
/* Tests various maps by making sure they all agree on the same answers. */
89
@RunWith(classOf[JUnit4])
@@ -26,4 +27,12 @@ class ArraySortingTest {
2627
assert( test(6) == 1 )
2728
assert( (test,cant).zipped.forall(_ == _.i) )
2829
}
30+
31+
@Test
32+
def testSortInPlace: Unit = {
33+
val arr = Array(3, 2, 1)
34+
arr.sortInPlace()
35+
36+
assertEquals(ArraySeq(1, 2, 3), ArraySeq.make(arr))
37+
}
2938
}

0 commit comments

Comments
 (0)