From 8f1d1a03e90901f0a37d186f6d3ef8f42362443a Mon Sep 17 00:00:00 2001 From: Mark Perry Date: Thu, 31 Jul 2014 09:59:55 +1000 Subject: [PATCH] GROOVY-6992: Added support for collecting over sets --- .../groovy/runtime/DefaultGroovyMethods.java | 46 ++++++++++++++++++- .../runtime/DefaultGroovyMethodsSupport.java | 7 +++ src/test/groovy/MapTest.groovy | 4 +- src/test/groovy/SetTest.groovy | 16 +++++++ 4 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java index c89ac4cb23..be58dc9e53 100644 --- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java +++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java @@ -2631,6 +2631,50 @@ public static List collect(Collection self, @ClosureParams(FirstPara return (List) collect(self, new ArrayList(self.size()), transform); } + /** + * Iterates through this Set transforming each value into a new value using the transform closure + * and adding it to the supplied collector. + *
assert [1,2,3] as HashSet == [2,4,5,6].collect { (int)(it / 2) }
+ * + * @param self a set + * @param collector the Set to which the transformed values are added + * @param transform the closure used to transform each item of the collection + * @return the collector with all transformed values added to it + */ + public static Set collect(Set self, Set collector, @ClosureParams(FirstParam.FirstGenericType.class) Closure transform) { + return collectSet(self, collector, transform); + } + + /** + * Iterates through this set transforming each entry into a new value using the transform closure + * returning a list of transformed values. + *
assert [1,2,3] as Set == [2,4,5,6].collect { (int) (it / 2) }
+ * + * @param self a set + * @param transform the closure used to transform each item of the collection + * @return a List of the transformed values + */ + public static Set collect(Set self, @ClosureParams(FirstParam.FirstGenericType.class) Closure transform) { + return collectSet(self, DefaultGroovyMethods.defaultSet(), transform); + } + + /** + * Iterates through this set transforming each entry into a new value using Closure.IDENTITY + * as a transformer, basically returning a set of items copied from the original collection. + *
assert [1,2,3] as Set == ([1,2,3] as Set).collect()
+ * + * @param self a set + * @return a Set of the transformed values + * @see Closure#IDENTITY + */ + public static Set collect(Set self) { + return collectSet(self, DefaultGroovyMethods.defaultSet(), Closure.IDENTITY); + } + + private static Set defaultSet() { + return new LinkedHashSet(); + } + /** * Iterates through this collection transforming each entry into a new value using Closure.IDENTITY * as a transformer, basically returning a list of items copied from the original collection. @@ -4063,7 +4107,7 @@ public static Set> permutations(List self) { * @since 2.2.0 */ public static List permutations(Iterable self, Closure function) { - return collect(permutations(self),function); + return collect((Collection) permutations(self),function); } /** diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java index 437f5f5afa..65fea2822e 100644 --- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java +++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethodsSupport.java @@ -15,9 +15,12 @@ */ package org.codehaus.groovy.runtime; +import groovy.lang.Closure; import groovy.lang.EmptyRange; import groovy.lang.IntRange; import groovy.lang.Range; +import groovy.transform.stc.ClosureParams; +import groovy.transform.stc.FirstParam; import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation; import java.io.Closeable; @@ -127,6 +130,10 @@ private static Object cloneObject(Object orig) { return null; } + protected static Set collectSet(Set self, Set collector, @ClosureParams(FirstParam.FirstGenericType.class) Closure transform) { + return (Set) DefaultGroovyMethods.collect((Collection) self, collector, transform); + } + protected static Collection createSimilarOrDefaultCollection(Object object) { if (object instanceof Collection) { return createSimilarCollection((Collection) object); diff --git a/src/test/groovy/MapTest.groovy b/src/test/groovy/MapTest.groovy index 2ac090d254..578c05ce15 100644 --- a/src/test/groovy/MapTest.groovy +++ b/src/test/groovy/MapTest.groovy @@ -117,7 +117,7 @@ class MapTest extends GroovyTestCase { assert map1 == control map1 = [a:1, b:2] - map1.putAll(map3.entrySet().collect{ [it.value, it.key] as MapEntry }) + map1.putAll(map3.entrySet().toList().collect{ [it.value, it.key] as MapEntry }) assert map1 == control map1 = [a:1, b:2] @@ -137,7 +137,7 @@ class MapTest extends GroovyTestCase { assert control == map1 + map2.entrySet() assert map1 == [a:1, b:2] - assert control == map1 + map3.entrySet().collect{ [it.value, it.key] as MapEntry } + assert control == map1 + map3.entrySet().toList().collect{ [it.value, it.key] as MapEntry } assert map1 == [a:1, b:2] map1 = [a:1, b:2] diff --git a/src/test/groovy/SetTest.groovy b/src/test/groovy/SetTest.groovy index f534cc9ad0..26e6ede7f1 100644 --- a/src/test/groovy/SetTest.groovy +++ b/src/test/groovy/SetTest.groovy @@ -39,6 +39,22 @@ class SetTest extends GroovyTestCase { assert flat == [3, 4, 5, 6, 7, 46, 78, "erer"] as Set } + void testCollect() { + def s1 = [1, 1, 2] as Set + assert(s1 instanceof Set) + def s2 = s1.collect { + (it + 1).toString() + } + assert(s2 == ["2", "3"] as Set) + def s3 = s1.collect { + s1 + } + assert(s3 == [[1, 2] as Set] as Set) + s3.each { + assert(it instanceof Set) + } + } + void testFlattenSetOfMapsWithClosure() { Set orig = [[a:1, b:2], [c:3, d:4]] as Set def flat = orig.flatten{ it instanceof Map ? it.values() : it }