Skip to content

Commit d86c0d3

Browse files
committed
GROOVY-11653: Create DGM#sort(List) and AGM#sort(T[]) variants that take an IntRange
1 parent 52e07dd commit d86c0d3

2 files changed

Lines changed: 164 additions & 4 deletions

File tree

src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8107,7 +8107,7 @@ public static <T> T[] sort(T[] self, Comparator<? super T> comparator) {
81078107
}
81088108

81098109
/**
8110-
* Modifies this array so that its elements are in sorted order as determined by the given comparator.
8110+
* Sorts the elements from this array into sorted order as determined by the given comparator.
81118111
* If mutate is true, the array is sorted in place and returned. Otherwise, a new sorted
81128112
* array is returned and the original array remains unchanged.
81138113
* <pre class="groovyTestCase">
@@ -8151,7 +8151,26 @@ public static <T> T[] sort(T[] self, @ClosureParams(value=FromString.class,optio
81518151
}
81528152

81538153
/**
8154-
* Modifies this array so that its elements are in sorted order using the Closure to determine the correct ordering.
8154+
* Sorts the elements from this array with index values in the given index range
8155+
* into a newly created array using the Closure to determine the correct ordering.
8156+
* <p>
8157+
* If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
8158+
* its two parameters for order, returning a negative integer, zero, or a positive integer when the
8159+
* first parameter is less than, equal to, or greater than the second respectively. Otherwise,
8160+
* the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
8161+
* which is then used for further comparison.
8162+
*
8163+
* @param self the array containing the elements to be sorted
8164+
* @param closure a Closure used to determine the correct ordering
8165+
* @return the sorted array
8166+
* @since 5.0.0
8167+
*/
8168+
public static <T> T[] sort(T[] self, IntRange range, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
8169+
return sort(self, range, false, closure);
8170+
}
8171+
8172+
/**
8173+
* Sorts the elements from this array into sorted order using the Closure to determine the correct ordering.
81558174
* If mutate is false, a new array is returned and the original array remains unchanged.
81568175
* Otherwise, the original array is sorted in place and returned.
81578176
* <p>
@@ -8170,7 +8189,7 @@ public static <T> T[] sort(T[] self, @ClosureParams(value=FromString.class,optio
81708189
* </pre>
81718190
*
81728191
* @param self the array to be sorted
8173-
* @param mutate false will always cause a new array to be created, true will mutate arrays in place
8192+
* @param mutate false causes a new array to be created, true will mutate arrays in place
81748193
* @param closure a Closure used to determine the correct ordering
81758194
* @return the sorted array
81768195
* @since 1.8.1
@@ -8182,6 +8201,61 @@ public static <T> T[] sort(T[] self, boolean mutate, @ClosureParams(value=FromSt
81828201
return self;
81838202
}
81848203

8204+
/**
8205+
* Sorts the elements with index values in the given index range
8206+
* into sorted order using the Closure to determine the correct ordering.
8207+
* If mutate is false, a new array is returned and the original array remains unchanged.
8208+
* Otherwise, the original array is sorted in place and returned.
8209+
* <p>
8210+
* If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
8211+
* its two parameters for order, returning a negative integer, zero, or a positive integer when the
8212+
* first parameter is less than, equal to, or greater than the second respectively. Otherwise,
8213+
* the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
8214+
* which is then used for further comparison.
8215+
* <pre class="groovyTestCase">
8216+
* // an array with some odd then even numbers
8217+
* Integer[] nums = [5, 9, 1, 7, 3, 4, 8, 6, 0, 2]
8218+
*
8219+
* // sort odds ascending, evens descending
8220+
* assert nums.sort(0..4, false) { it }.sort(5..9, false) { -it }
8221+
* == [1, 3, 5, 7, 9, 8, 6, 4, 2, 0]
8222+
* // sort odds descending, evens descending
8223+
* assert nums.sort(0..&lt;5, false) { -it }.sort(4&lt;..&lt;10, false) { -it }
8224+
* == [9, 7, 5, 3, 1, 8, 6, 4, 2, 0]
8225+
* // sort odds descending, evens ascending
8226+
* assert nums.sort(0..&lt;5, false) { -it }.sort(5..-1, false) { it }
8227+
* == [9, 7, 5, 3, 1, 0, 2, 4, 6, 8]
8228+
* // leave first and last numbers, sort remaining odds ascending, remaining evens descending
8229+
* assert nums.sort(1..4, false) { it }.sort(5..-2, false) { -it }
8230+
* == [5, 1, 3, 7, 9, 8, 6, 4, 0, 2]
8231+
* // leave first and last numbers, sort remaining odds descending, remaining evens ascending
8232+
* assert nums.sort(1..4, false) { -it }.sort(5..-2, false) { it }
8233+
* == [5, 9, 7, 3, 1, 0, 4, 6, 8, 2]
8234+
* // leave first and last odds and evens, sort remaining odds ascending, remaining evens descending
8235+
* assert nums.sort(0&lt;..&lt;4, false) { it }.sort(5&lt;..&lt;9, false) { -it }
8236+
* == [5, 1, 7, 9, 3, 4, 8, 6, 0, 2]
8237+
* // leave first and last odds and evens, sort remaining odds descending, remaining evens ascending
8238+
* assert nums.sort(0&lt;..&lt;4, false) { -it }.sort(5&lt;..&lt;-1, false) { it }
8239+
* == [5, 9, 7, 1, 3, 4, 0, 6, 8, 2]
8240+
* </pre>
8241+
*
8242+
* @param self the array to be sorted
8243+
* @param range the inclusive range of index values over which to sort
8244+
* @param mutate false causes a new array to be created, true will mutate arrays in place
8245+
* @param closure a Closure used to determine the correct ordering
8246+
* @return the sorted array
8247+
* @since 5.0.0
8248+
*/
8249+
public static <T> T[] sort(T[] self, IntRange range, boolean mutate, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
8250+
Objects.requireNonNull(self);
8251+
RangeInfo info = range.subListBorders(self.length);
8252+
Objects.checkFromToIndex(info.from, info.to, self.length);
8253+
if (!mutate) self = self.clone();
8254+
Comparator<T> c = closure.getMaximumNumberOfParameters() == 1 ? new OrderBy<>(closure) : new ClosureComparator<>(closure);
8255+
Arrays.sort(self, info.from, info.to, c);
8256+
return self;
8257+
}
8258+
81858259
//--------------------------------------------------------------------------
81868260
// split
81878261

src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13455,7 +13455,7 @@ public static <T> Iterator<T> sort(Iterator<T> self, Comparator<? super T> compa
1345513455
* </pre>
1345613456
*
1345713457
* @param self the Iterable to be sorted
13458-
* @param mutate false will always cause a new list to be created, true will mutate lists in place
13458+
* @param mutate false causes a new list to be created, true will mutate lists in place
1345913459
* @param comparator a Comparator used for the comparison
1346013460
* @return a sorted List
1346113461
* @since 2.2.0
@@ -13466,6 +13466,78 @@ public static <T> List<T> sort(Iterable<T> self, boolean mutate, Comparator<? su
1346613466
return list;
1346713467
}
1346813468

13469+
/**
13470+
* Sorts elements in the given index range using the given Closure to determine the ordering.
13471+
* If mutate is true, it is sorted in place and returned. Otherwise, the elements are first placed
13472+
* into a new list which is then sorted and returned, leaving the original List unchanged.
13473+
*
13474+
* <pre class="groovyTestCase">
13475+
* // a list with some odd then even numbers
13476+
* def nums = [5, 9, 1, 7, 3, 4, 8, 6, 0, 2]
13477+
*
13478+
* // sort odds ascending, evens descending
13479+
* assert nums.sort(0..4, false) { it }.sort(5..9, false) { -it }
13480+
* == [1, 3, 5, 7, 9, 8, 6, 4, 2, 0]
13481+
* // sort odds descending, evens descending
13482+
* assert nums.sort(0..&lt;5, false) { -it }.sort(4&lt;..&lt;10, false) { -it }
13483+
* == [9, 7, 5, 3, 1, 8, 6, 4, 2, 0]
13484+
* // sort odds descending, evens ascending
13485+
* assert nums.sort(0..&lt;5, false) { -it }.sort(5..-1, false) { it }
13486+
* == [9, 7, 5, 3, 1, 0, 2, 4, 6, 8]
13487+
* // leave first and last numbers, sort remaining odds ascending, remaining evens descending
13488+
* assert nums.sort(1..4, false) { it }.sort(5..-2, false) { -it }
13489+
* == [5, 1, 3, 7, 9, 8, 6, 4, 0, 2]
13490+
* // leave first and last numbers, sort remaining odds descending, remaining evens ascending
13491+
* assert nums.sort(1..4, false) { -it }.sort(5..-2, false) { it }
13492+
* == [5, 9, 7, 3, 1, 0, 4, 6, 8, 2]
13493+
* // leave first and last odds and evens, sort remaining odds ascending, remaining evens descending
13494+
* assert nums.sort(0&lt;..&lt;4, false) { it }.sort(5&lt;..&lt;9, false) { -it }
13495+
* == [5, 1, 7, 9, 3, 4, 8, 6, 0, 2]
13496+
* // leave first and last odds and evens, sort remaining odds descending, remaining evens ascending
13497+
* assert nums.sort(0&lt;..&lt;4, false) { -it }.sort(5&lt;..&lt;-1, false) { it }
13498+
* == [5, 9, 7, 1, 3, 4, 0, 6, 8, 2]
13499+
* </pre>
13500+
*
13501+
* @param self the List to be sorted
13502+
* @param range the inclusive range of index values over which to sort
13503+
* @param mutate false causes a new list to be created, true will mutate lists in place
13504+
* @param closure a Closure used to determine the correct ordering
13505+
* @return a sorted List
13506+
* @since 5.0.0
13507+
*/
13508+
public static <T> List<T> sort(List<T> self, IntRange range, boolean mutate, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
13509+
Objects.requireNonNull(self);
13510+
RangeInfo info = range.subListBorders(self.size());
13511+
Objects.checkFromToIndex(info.from, info.to, self.size());
13512+
T[] a = (T[]) self.toArray();
13513+
Comparator<T> c = closure.getMaximumNumberOfParameters() == 1 ? new OrderBy<>(closure) : new ClosureComparator<>(closure);
13514+
Arrays.sort(a, info.from, info.to, c);
13515+
if (!mutate) {
13516+
return Arrays.asList(a);
13517+
}
13518+
ListIterator<T> i = self.listIterator();
13519+
for (T e : a) {
13520+
i.next();
13521+
i.set(e);
13522+
}
13523+
return self;
13524+
}
13525+
13526+
/**
13527+
* A sort variant that takes an index range and always mutates the original list.
13528+
* <pre class="groovyTestCase">
13529+
* def nums = [5, 9, 1, 7, 3, 4, 8, 6, 0, 2]
13530+
* nums.sort(0..4) { it }
13531+
* assert nums == [1, 3, 5, 7, 9, 4, 8, 6, 0, 2]
13532+
* </pre>
13533+
*
13534+
* @see #sort(List, IntRange, boolean, Closure)
13535+
* @return the sorted list
13536+
*/
13537+
public static <T> List<T> sort(List<T> self, IntRange range, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
13538+
return sort(self, range, true, closure);
13539+
}
13540+
1346913541
/**
1347013542
* Sorts the given iterator items into a sorted iterator using the Closure to determine the correct ordering.
1347113543
* The original iterator will be fully processed after the method call.
@@ -15227,6 +15299,20 @@ public static <T> Iterator<T> toSorted(Iterator<T> self, @ClosureParams(value=Fr
1522715299
return toSorted(self, comparator);
1522815300
}
1522915301

15302+
/**
15303+
* A sort variant that takes an index range and never modifies the original list.
15304+
* <pre class="groovyTestCase">
15305+
* def nums = [5, 9, 1, 7, 3, 4, 8, 6, 0, 2]
15306+
* assert nums.toSorted(0..4) { it } == [1, 3, 5, 7, 9, 4, 8, 6, 0, 2]
15307+
* </pre>
15308+
*
15309+
* @see #sort(List, IntRange, boolean, Closure)
15310+
* @return the sorted list
15311+
*/
15312+
public static <T> List<T> toSorted(List<T> self, IntRange range, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
15313+
return sort(self, range, false, closure);
15314+
}
15315+
1523015316
/**
1523115317
* Sorts the elements from the given map into a new ordered map using
1523215318
* a {@link NumberAwareComparator} on map entry values to determine the resulting order.

0 commit comments

Comments
 (0)