diff --git a/pom.xml b/pom.xml
index 02a5294..db39118 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
fi.solita.utils
functional-utils
- 0.12.48
+ 0.12.49
diff --git a/src/main/java/fi/solita/utils/functional/FunctionalM.java b/src/main/java/fi/solita/utils/functional/FunctionalM.java
index b909338..d579eb7 100644
--- a/src/main/java/fi/solita/utils/functional/FunctionalM.java
+++ b/src/main/java/fi/solita/utils/functional/FunctionalM.java
@@ -6,6 +6,7 @@
import static fi.solita.utils.functional.Collections.newMultimap;
import static fi.solita.utils.functional.Collections.newSet;
import static fi.solita.utils.functional.Collections.newSortedMap;
+import static fi.solita.utils.functional.Functional.repeat;
import java.util.List;
import java.util.Map;
@@ -52,28 +53,28 @@ public Map.Entry apply(Map.Entry t) {
* @return elements in {@code map} transformed with {@code f}.
*/
public static SortedMap> map(Apply f, SortedMap> map) {
- return map == null ? null : (SortedMap>) newSortedMap(SemiGroups.>fail(), map.comparator(), Functional.map(FunctionalM.valueMapper(f), map.entrySet()));
+ return map == null ? null : (SortedMap>) newSortedMap(SemiGroups.>fail(), map.comparator(), FunctionalImpl.map(FunctionalM.valueMapper(f), map.entrySet()));
}
/**
* @return {@code map} with elements of values transformed with {@code f}.
*/
public static Map> mapValues(Apply f, Map> map) {
- return map == null ? null : newLinkedMap(SemiGroups.>fail(), Functional.map(FunctionalM.valueMapper(f), map.entrySet()));
+ return map == null ? null : newLinkedMap(SemiGroups.>fail(), FunctionalImpl.map(FunctionalM.valueMapper(f), map.entrySet()));
}
/**
* @return {@code map} with elements of values transformed with {@code f}.
*/
public static Map> mapValueList(Apply f, Map> map) {
- return map == null ? null : newLinkedMap(SemiGroups.>fail(), Functional.map(FunctionalM.valueMapperList(f), map.entrySet()));
+ return map == null ? null : newLinkedMap(SemiGroups.>fail(), FunctionalImpl.map(FunctionalM.valueMapperList(f), map.entrySet()));
}
/**
* @return {@code map} with elements of values transformed with {@code f}.
*/
public static Map> mapValueSet(Apply f, Map> map) {
- return map == null ? null : newLinkedMap(SemiGroups.>fail(), Functional.map(FunctionalM.valueMapperSet(f), map.entrySet()));
+ return map == null ? null : newLinkedMap(SemiGroups.>fail(), FunctionalImpl.map(FunctionalM.valueMapperSet(f), map.entrySet()));
}
/**
@@ -90,6 +91,38 @@ public static Map mapValue(Apply f, Map map) {
return map == null ? null : newLinkedMap(SemiGroups.fail(), FunctionalImpl.map(Transformers.key(), Transformers.value().andThen(f), map.entrySet()));
}
+ public static > Iterable> flatten(Map map) {
+ return map == null ? null : FunctionalImpl.flatMap(new Apply,Iterable>>() {
+ @Override
+ public Iterable> apply(final Map.Entry t) {
+ return FunctionalImpl.zip(repeat(t.getKey()), t.getValue());
+ }
+ }, map.entrySet());
+ }
+
+ public static >> Iterable> flatten2(Map map) {
+ return map == null ? null : FunctionalImpl.flatMap(new Apply,Iterable>>() {
+ @Override
+ public Iterable> apply(final Map.Entry t) {
+ return FunctionalImpl.map(Transformers.prependPair(t.getKey()), (Iterable extends Map.Entry>)t.getValue());
+ }
+ }, map.entrySet());
+ }
+
+ public static >> Iterable> flatten3(Map map) {
+ return map == null ? null : FunctionalImpl.flatMap(new Apply,Iterable>>() {
+ @Override
+ public Iterable> apply(final Map.Entry t) {
+ return FunctionalImpl.map(new Apply, Tuple4>() {
+ @Override
+ public Tuple4 apply(Tuple3 tt) {
+ return tt.prepend(t.getKey());
+ }
+ }, t.getValue());
+ }
+ }, map.entrySet());
+ }
+
private static Transformer>,Map.Entry>> valueMapper(final Apply f) {
return new Transformer>, Map.Entry>>() {
@Override
@@ -124,11 +157,15 @@ public static final Map> groupBy(Apply super T,G> f, Iterabl
return FunctionalImpl.groupBy(f, xs);
}
+ public static final Map> groupBy(Apply super T,G> key, Apply super T,V> value, Iterable xs) {
+ return newMultimap(FunctionalImpl.map(Pair.fanout(key, value), xs));
+ }
+
/**
* @return tuples in {@code xs} grouped by first value of the tuple.
*/
public static final & Tuple.Tailable> Map> groupByFirst(Iterable xs) {
- return newMultimap(Functional.map(new Apply>() {
+ return newMultimap(FunctionalImpl.map(new Apply>() {
public Map.Entry apply(T t) {
return Pair.of(t.get_1(), t.drop1());
}
@@ -139,7 +176,7 @@ public Map.Entry apply(T t) {
* @return tuples in {@code xs} grouped by first value of the tuple, duplicates handled with {@code valueCombiner}.
*/
public static final & Tuple.Tailable> Map groupByFirst(SemiGroup valueCombiner, Iterable xs) {
- return newMap(valueCombiner, Functional.map(new Apply>() {
+ return newMap(valueCombiner, FunctionalImpl.map(new Apply>() {
public Map.Entry apply(T t) {
return Pair.of(t.get_1(), t.drop1());
}
diff --git a/src/main/java/fi/solita/utils/functional/Pair.java b/src/main/java/fi/solita/utils/functional/Pair.java
index 295e641..8e067bf 100644
--- a/src/main/java/fi/solita/utils/functional/Pair.java
+++ b/src/main/java/fi/solita/utils/functional/Pair.java
@@ -14,7 +14,7 @@ public static Pair of(LEFT left, RIGHT right) {
return new Pair(left, right);
}
- public static Apply> fanout(final Apply l, final Apply r) {
+ public static Apply> fanout(final Apply super T, LEFT> l, final Apply super T, RIGHT> r) {
return new Function1>() {
@Override
public Pair apply(T t) {