This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new d86c0d3f11 GROOVY-11653: Create DGM#sort(List) and AGM#sort(T[]) 
variants that take an IntRange
d86c0d3f11 is described below

commit d86c0d3f11c537853c994619c283963bfd6f5478
Author: Paul King <[email protected]>
AuthorDate: Tue May 6 14:56:24 2025 +1000

    GROOVY-11653: Create DGM#sort(List) and AGM#sort(T[]) variants that take an 
IntRange
---
 .../groovy/runtime/ArrayGroovyMethods.java         | 80 +++++++++++++++++++-
 .../groovy/runtime/DefaultGroovyMethods.java       | 88 +++++++++++++++++++++-
 2 files changed, 164 insertions(+), 4 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java 
b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
index e0ac6bd481..6a3dd0b42b 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
@@ -8107,7 +8107,7 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Modifies this array so that its elements are in sorted order as 
determined by the given comparator.
+     * Sorts the elements from this array into sorted order as determined by 
the given comparator.
      * If mutate is true, the array is sorted in place and returned. 
Otherwise, a new sorted
      * array is returned and the original array remains unchanged.
      * <pre class="groovyTestCase">
@@ -8151,7 +8151,26 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Modifies this array so that its elements are in sorted order using the 
Closure to determine the correct ordering.
+     * Sorts the elements from this array with index values in the given index 
range
+     * into a newly created array using the Closure to determine the correct 
ordering.
+     * <p>
+     * If the closure has two parameters it is used like a traditional 
Comparator. I.e. it should compare
+     * its two parameters for order, returning a negative integer, zero, or a 
positive integer when the
+     * first parameter is less than, equal to, or greater than the second 
respectively. Otherwise,
+     * the Closure is assumed to take a single parameter and return a 
Comparable (typically an Integer)
+     * which is then used for further comparison.
+     *
+     * @param self the array containing the elements to be sorted
+     * @param closure a Closure used to determine the correct ordering
+     * @return the sorted array
+     * @since 5.0.0
+     */
+    public static <T> T[] sort(T[] self, IntRange range, 
@ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
+        return sort(self, range, false, closure);
+    }
+
+    /**
+     * Sorts the elements from this array into sorted order using the Closure 
to determine the correct ordering.
      * If mutate is false, a new array is returned and the original array 
remains unchanged.
      * Otherwise, the original array is sorted in place and returned.
      * <p>
@@ -8170,7 +8189,7 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
      * </pre>
      *
      * @param self    the array to be sorted
-     * @param mutate  false will always cause a new array to be created, true 
will mutate arrays in place
+     * @param mutate  false causes a new array to be created, true will mutate 
arrays in place
      * @param closure a Closure used to determine the correct ordering
      * @return the sorted array
      * @since 1.8.1
@@ -8182,6 +8201,61 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
         return self;
     }
 
+    /**
+     * Sorts the elements with index values in the given index range
+     * into sorted order using the Closure to determine the correct ordering.
+     * If mutate is false, a new array is returned and the original array 
remains unchanged.
+     * Otherwise, the original array is sorted in place and returned.
+     * <p>
+     * If the closure has two parameters it is used like a traditional 
Comparator. I.e. it should compare
+     * its two parameters for order, returning a negative integer, zero, or a 
positive integer when the
+     * first parameter is less than, equal to, or greater than the second 
respectively. Otherwise,
+     * the Closure is assumed to take a single parameter and return a 
Comparable (typically an Integer)
+     * which is then used for further comparison.
+     * <pre class="groovyTestCase">
+     * // an array with some odd then even numbers
+     * Integer[] nums = [5, 9, 1, 7, 3, 4, 8, 6, 0, 2]
+     *
+     * // sort odds ascending, evens descending
+     * assert nums.sort(0..4, false) { it }.sort(5..9, false) { -it }
+     *  == [1, 3, 5, 7, 9, 8, 6, 4, 2, 0]
+     * // sort odds descending, evens descending
+     * assert nums.sort(0..&lt;5, false) { -it }.sort(4&lt;..&lt;10, false) { 
-it }
+     *  == [9, 7, 5, 3, 1, 8, 6, 4, 2, 0]
+     * // sort odds descending, evens ascending
+     * assert nums.sort(0..&lt;5, false) { -it }.sort(5..-1, false) { it }
+     *  == [9, 7, 5, 3, 1, 0, 2, 4, 6, 8]
+     * // leave first and last numbers, sort remaining odds ascending, 
remaining evens descending
+     * assert nums.sort(1..4, false) { it }.sort(5..-2, false) { -it }
+     *  == [5, 1, 3, 7, 9, 8, 6, 4, 0, 2]
+     * // leave first and last numbers, sort remaining odds descending, 
remaining evens ascending
+     * assert nums.sort(1..4, false) { -it }.sort(5..-2, false) { it }
+     *  == [5, 9, 7, 3, 1, 0, 4, 6, 8, 2]
+     * // leave first and last odds and evens, sort remaining odds ascending, 
remaining evens descending
+     * assert nums.sort(0&lt;..&lt;4, false) { it }.sort(5&lt;..&lt;9, false) 
{ -it }
+     *  == [5, 1, 7, 9, 3, 4, 8, 6, 0, 2]
+     * // leave first and last odds and evens, sort remaining odds descending, 
remaining evens ascending
+     * assert nums.sort(0&lt;..&lt;4, false) { -it }.sort(5&lt;..&lt;-1, 
false) { it }
+     *  == [5, 9, 7, 1, 3, 4, 0, 6, 8, 2]
+     * </pre>
+     *
+     * @param self    the array to be sorted
+     * @param range   the inclusive range of index values over which to sort
+     * @param mutate  false causes a new array to be created, true will mutate 
arrays in place
+     * @param closure a Closure used to determine the correct ordering
+     * @return the sorted array
+     * @since 5.0.0
+     */
+    public static <T> T[] sort(T[] self, IntRange range, boolean mutate, 
@ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
+        Objects.requireNonNull(self);
+        RangeInfo info = range.subListBorders(self.length);
+        Objects.checkFromToIndex(info.from, info.to, self.length);
+        if (!mutate) self = self.clone();
+        Comparator<T> c = closure.getMaximumNumberOfParameters() == 1 ? new 
OrderBy<>(closure) : new ClosureComparator<>(closure);
+        Arrays.sort(self, info.from, info.to, c);
+        return self;
+    }
+
     
//--------------------------------------------------------------------------
     // split
 
diff --git 
a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java 
b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index c47078861e..1f26369fcc 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -13455,7 +13455,7 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
      * </pre>
      *
      * @param self       the Iterable to be sorted
-     * @param mutate     false will always cause a new list to be created, 
true will mutate lists in place
+     * @param mutate     false causes a new list to be created, true will 
mutate lists in place
      * @param comparator a Comparator used for the comparison
      * @return a sorted List
      * @since 2.2.0
@@ -13466,6 +13466,78 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
         return list;
     }
 
+    /**
+     * Sorts elements in the given index range using the given Closure to 
determine the ordering.
+     * If mutate is true, it is sorted in place and returned. Otherwise, the 
elements are first placed
+     * into a new list which is then sorted and returned, leaving the original 
List unchanged.
+     *
+     * <pre class="groovyTestCase">
+     * // a list with some odd then even numbers
+     * def nums = [5, 9, 1, 7, 3, 4, 8, 6, 0, 2]
+     *
+     * // sort odds ascending, evens descending
+     * assert nums.sort(0..4, false) { it }.sort(5..9, false) { -it }
+     *  == [1, 3, 5, 7, 9, 8, 6, 4, 2, 0]
+     * // sort odds descending, evens descending
+     * assert nums.sort(0..&lt;5, false) { -it }.sort(4&lt;..&lt;10, false) { 
-it }
+     *  == [9, 7, 5, 3, 1, 8, 6, 4, 2, 0]
+     * // sort odds descending, evens ascending
+     * assert nums.sort(0..&lt;5, false) { -it }.sort(5..-1, false) { it }
+     *  == [9, 7, 5, 3, 1, 0, 2, 4, 6, 8]
+     * // leave first and last numbers, sort remaining odds ascending, 
remaining evens descending
+     * assert nums.sort(1..4, false) { it }.sort(5..-2, false) { -it }
+     *  == [5, 1, 3, 7, 9, 8, 6, 4, 0, 2]
+     * // leave first and last numbers, sort remaining odds descending, 
remaining evens ascending
+     * assert nums.sort(1..4, false) { -it }.sort(5..-2, false) { it }
+     *  == [5, 9, 7, 3, 1, 0, 4, 6, 8, 2]
+     * // leave first and last odds and evens, sort remaining odds ascending, 
remaining evens descending
+     * assert nums.sort(0&lt;..&lt;4, false) { it }.sort(5&lt;..&lt;9, false) 
{ -it }
+     *  == [5, 1, 7, 9, 3, 4, 8, 6, 0, 2]
+     * // leave first and last odds and evens, sort remaining odds descending, 
remaining evens ascending
+     * assert nums.sort(0&lt;..&lt;4, false) { -it }.sort(5&lt;..&lt;-1, 
false) { it }
+     *  == [5, 9, 7, 1, 3, 4, 0, 6, 8, 2]
+     * </pre>
+     *
+     * @param self    the List to be sorted
+     * @param range   the inclusive range of index values over which to sort
+     * @param mutate  false causes a new list to be created, true will mutate 
lists in place
+     * @param closure a Closure used to determine the correct ordering
+     * @return a sorted List
+     * @since 5.0.0
+     */
+    public static <T> List<T> sort(List<T> self, IntRange range, boolean 
mutate, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> 
closure) {
+        Objects.requireNonNull(self);
+        RangeInfo info = range.subListBorders(self.size());
+        Objects.checkFromToIndex(info.from, info.to, self.size());
+        T[] a = (T[]) self.toArray();
+        Comparator<T> c = closure.getMaximumNumberOfParameters() == 1 ? new 
OrderBy<>(closure) : new ClosureComparator<>(closure);
+        Arrays.sort(a, info.from, info.to, c);
+        if (!mutate) {
+            return Arrays.asList(a);
+        }
+        ListIterator<T> i = self.listIterator();
+        for (T e : a) {
+            i.next();
+            i.set(e);
+        }
+        return self;
+    }
+
+    /**
+     * A sort variant that takes an index range and always mutates the 
original list.
+     * <pre class="groovyTestCase">
+     * def nums = [5, 9, 1, 7, 3, 4, 8, 6, 0, 2]
+     * nums.sort(0..4) { it }
+     * assert nums == [1, 3, 5, 7, 9, 4, 8, 6, 0, 2]
+     * </pre>
+     *
+     * @see #sort(List, IntRange, boolean, Closure)
+     * @return the sorted list
+     */
+    public static <T> List<T> sort(List<T> self, IntRange range, 
@ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
+        return sort(self, range, true, closure);
+    }
+
     /**
      * Sorts the given iterator items into a sorted iterator using the Closure 
to determine the correct ordering.
      * The original iterator will be fully processed after the method call.
@@ -15227,6 +15299,20 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
         return toSorted(self, comparator);
     }
 
+    /**
+     * A sort variant that takes an index range and never modifies the 
original list.
+     * <pre class="groovyTestCase">
+     * def nums = [5, 9, 1, 7, 3, 4, 8, 6, 0, 2]
+     * assert nums.toSorted(0..4) { it } == [1, 3, 5, 7, 9, 4, 8, 6, 0, 2]
+     * </pre>
+     *
+     * @see #sort(List, IntRange, boolean, Closure)
+     * @return the sorted list
+     */
+    public static <T> List<T> toSorted(List<T> self, IntRange range, 
@ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
+        return sort(self, range, false, closure);
+    }
+
     /**
      * Sorts the elements from the given map into a new ordered map using
      * a {@link NumberAwareComparator} on map entry values to determine the 
resulting order.

Reply via email to