Skip to content

Commit

Permalink
some functions for Map handling
Browse files Browse the repository at this point in the history
  • Loading branch information
jyrimatti committed Apr 8, 2024
1 parent f14ee89 commit 3f64479
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 8 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>fi.solita.utils</groupId>
<artifactId>functional-utils</artifactId>
<version>0.12.48</version>
<version>0.12.49</version>
<build>
<resources>
<resource>
Expand Down
49 changes: 43 additions & 6 deletions src/main/java/fi/solita/utils/functional/FunctionalM.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -52,28 +53,28 @@ public Map.Entry<K2, V2> apply(Map.Entry<K1, V1> t) {
* @return elements in {@code map} transformed with {@code f}.
*/
public static <T,V,R> SortedMap<T, Iterable<R>> map(Apply<V,R> f, SortedMap<T,? extends Iterable<V>> map) {
return map == null ? null : (SortedMap<T, Iterable<R>>) newSortedMap(SemiGroups.<Iterable<R>>fail(), map.comparator(), Functional.map(FunctionalM.<T,V,R>valueMapper(f), map.entrySet()));
return map == null ? null : (SortedMap<T, Iterable<R>>) newSortedMap(SemiGroups.<Iterable<R>>fail(), map.comparator(), FunctionalImpl.map(FunctionalM.<T,V,R>valueMapper(f), map.entrySet()));
}

/**
* @return {@code map} with elements of values transformed with {@code f}.
*/
public static <T,V,R> Map<T, Iterable<R>> mapValues(Apply<V,R> f, Map<T,? extends Iterable<V>> map) {
return map == null ? null : newLinkedMap(SemiGroups.<Iterable<R>>fail(), Functional.map(FunctionalM.<T,V,R>valueMapper(f), map.entrySet()));
return map == null ? null : newLinkedMap(SemiGroups.<Iterable<R>>fail(), FunctionalImpl.map(FunctionalM.<T,V,R>valueMapper(f), map.entrySet()));
}

/**
* @return {@code map} with elements of values transformed with {@code f}.
*/
public static <T,V,R> Map<T, List<R>> mapValueList(Apply<V,R> f, Map<T,? extends Iterable<V>> map) {
return map == null ? null : newLinkedMap(SemiGroups.<List<R>>fail(), Functional.map(FunctionalM.<T,V,R>valueMapperList(f), map.entrySet()));
return map == null ? null : newLinkedMap(SemiGroups.<List<R>>fail(), FunctionalImpl.map(FunctionalM.<T,V,R>valueMapperList(f), map.entrySet()));
}

/**
* @return {@code map} with elements of values transformed with {@code f}.
*/
public static <T,V,R> Map<T, Set<R>> mapValueSet(Apply<V,R> f, Map<T,? extends Iterable<V>> map) {
return map == null ? null : newLinkedMap(SemiGroups.<Set<R>>fail(), Functional.map(FunctionalM.<T,V,R>valueMapperSet(f), map.entrySet()));
return map == null ? null : newLinkedMap(SemiGroups.<Set<R>>fail(), FunctionalImpl.map(FunctionalM.<T,V,R>valueMapperSet(f), map.entrySet()));
}

/**
Expand All @@ -90,6 +91,38 @@ public static <K,V,R> Map<K, R> mapValue(Apply<V,R> f, Map<K,V> map) {
return map == null ? null : newLinkedMap(SemiGroups.<R>fail(), FunctionalImpl.map(Transformers.<K,V>key(), Transformers.<K,V>value().andThen(f), map.entrySet()));
}

public static <K,V,C extends Iterable<V>> Iterable<Pair<K, V>> flatten(Map<K,C> map) {
return map == null ? null : FunctionalImpl.flatMap(new Apply<Map.Entry<K,C>,Iterable<Pair<K,V>>>() {
@Override
public Iterable<Pair<K, V>> apply(final Map.Entry<K, C> t) {
return FunctionalImpl.zip(repeat(t.getKey()), t.getValue());
}
}, map.entrySet());
}

public static <K,V1,V2,C extends Iterable<? extends Map.Entry<V1,V2>>> Iterable<Tuple3<K,V1,V2>> flatten2(Map<K,C> map) {
return map == null ? null : FunctionalImpl.flatMap(new Apply<Map.Entry<K,C>,Iterable<Tuple3<K,V1,V2>>>() {
@Override
public Iterable<Tuple3<K,V1,V2>> apply(final Map.Entry<K, C> t) {
return FunctionalImpl.map(Transformers.<K,V1,V2>prependPair(t.getKey()), (Iterable<? extends Map.Entry<V1,V2>>)t.getValue());
}
}, map.entrySet());
}

public static <K,V1,V2,V3,C extends Iterable<Tuple3<V1,V2,V3>>> Iterable<Tuple4<K,V1,V2,V3>> flatten3(Map<K,C> map) {
return map == null ? null : FunctionalImpl.flatMap(new Apply<Map.Entry<K,C>,Iterable<Tuple4<K,V1,V2,V3>>>() {
@Override
public Iterable<Tuple4<K,V1,V2,V3>> apply(final Map.Entry<K, C> t) {
return FunctionalImpl.map(new Apply<Tuple3<V1,V2,V3>, Tuple4<K,V1,V2,V3>>() {
@Override
public Tuple4<K, V1, V2, V3> apply(Tuple3<V1, V2, V3> tt) {
return tt.prepend(t.getKey());
}
}, t.getValue());
}
}, map.entrySet());
}

private static <T,V,R> Transformer<Map.Entry<T, ? extends Iterable<V>>,Map.Entry<T, Iterable<R>>> valueMapper(final Apply<V,R> f) {
return new Transformer<Map.Entry<T, ? extends Iterable<V>>, Map.Entry<T, Iterable<R>>>() {
@Override
Expand Down Expand Up @@ -124,11 +157,15 @@ public static final <G, T> Map<G, List<T>> groupBy(Apply<? super T,G> f, Iterabl
return FunctionalImpl.groupBy(f, xs);
}

public static final <G,V,T> Map<G, List<V>> groupBy(Apply<? super T,G> key, Apply<? super T,V> value, Iterable<T> 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 <G, R, T extends Tuple._1<G> & Tuple.Tailable<R>> Map<G, List<R>> groupByFirst(Iterable<T> xs) {
return newMultimap(Functional.map(new Apply<T, Map.Entry<G,R>>() {
return newMultimap(FunctionalImpl.map(new Apply<T, Map.Entry<G,R>>() {
public Map.Entry<G, R> apply(T t) {
return Pair.of(t.get_1(), t.drop1());
}
Expand All @@ -139,7 +176,7 @@ public Map.Entry<G, R> apply(T t) {
* @return tuples in {@code xs} grouped by first value of the tuple, duplicates handled with {@code valueCombiner}.
*/
public static final <G, R, T extends Tuple._1<G> & Tuple.Tailable<R>> Map<G, R> groupByFirst(SemiGroup<R> valueCombiner, Iterable<T> xs) {
return newMap(valueCombiner, Functional.map(new Apply<T, Map.Entry<G,R>>() {
return newMap(valueCombiner, FunctionalImpl.map(new Apply<T, Map.Entry<G,R>>() {
public Map.Entry<G, R> apply(T t) {
return Pair.of(t.get_1(), t.drop1());
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/fi/solita/utils/functional/Pair.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static <LEFT, RIGHT> Pair<LEFT, RIGHT> of(LEFT left, RIGHT right) {
return new Pair<LEFT, RIGHT>(left, right);
}

public static <T, LEFT, RIGHT> Apply<T, Pair<LEFT, RIGHT>> fanout(final Apply<T, LEFT> l, final Apply<T, RIGHT> r) {
public static <T, LEFT, RIGHT> Apply<T, Pair<LEFT, RIGHT>> fanout(final Apply<? super T, LEFT> l, final Apply<? super T, RIGHT> r) {
return new Function1<T, Pair<LEFT,RIGHT>>() {
@Override
public Pair<LEFT, RIGHT> apply(T t) {
Expand Down

0 comments on commit 3f64479

Please sign in to comment.