1
1
package com .jnape .palatable .lambda .lens .lenses ;
2
2
3
+ import com .jnape .palatable .lambda .functions .builtin .fn2 .Filter ;
3
4
import com .jnape .palatable .lambda .lens .Lens ;
4
5
5
6
import java .util .Collection ;
8
9
import java .util .Map ;
9
10
import java .util .Optional ;
10
11
import java .util .Set ;
12
+ import java .util .function .Function ;
11
13
14
+ import static com .jnape .palatable .lambda .functions .builtin .fn2 .Eq .eq ;
15
+ import static com .jnape .palatable .lambda .functions .builtin .fn2 .Map .map ;
16
+ import static com .jnape .palatable .lambda .functions .builtin .fn2 .ToCollection .toCollection ;
12
17
import static com .jnape .palatable .lambda .lens .Lens .lens ;
13
18
import static com .jnape .palatable .lambda .lens .Lens .simpleLens ;
14
19
import static com .jnape .palatable .lambda .lens .functions .View .view ;
15
20
import static com .jnape .palatable .lambda .lens .lenses .OptionalLens .unLiftA ;
21
+ import static java .util .stream .Collectors .toMap ;
16
22
import static java .util .stream .Collectors .toSet ;
17
23
18
24
/**
@@ -24,8 +30,7 @@ private MapLens() {
24
30
}
25
31
26
32
/**
27
- * Convenience static factory method for creating a lens that focuses on a copy of a Map. Useful for composition to
28
- * avoid mutating a map reference.
33
+ * A lens that focuses on a copy of a Map. Useful for composition to avoid mutating a map reference.
29
34
*
30
35
* @param <K> the key type
31
36
* @param <V> the value type
@@ -36,8 +41,7 @@ public static <K, V> Lens.Simple<Map<K, V>, Map<K, V>> asCopy() {
36
41
}
37
42
38
43
/**
39
- * Convenience static factory method for creating a lens that focuses on a value at a key in a map, as an {@link
40
- * Optional}.
44
+ * A lens that focuses on a value at a key in a map, as an {@link Optional}.
41
45
*
42
46
* @param k the key to focus on
43
47
* @param <K> the key type
@@ -52,8 +56,7 @@ public static <K, V> Lens<Map<K, V>, Map<K, V>, Optional<V>, V> valueAt(K k) {
52
56
}
53
57
54
58
/**
55
- * Convenience static factory method for creating a lens that focuses on a value at a key in a map, falling back to
56
- * <code>defaultV</code> if the value is missing.
59
+ * A lens that focuses on a value at a key in a map, falling back to <code>defaultV</code> if the value is missing.
57
60
*
58
61
* @param k the key to focus on
59
62
* @param defaultValue the default value to use in case of a missing value at key
@@ -67,7 +70,7 @@ public static <K, V> Lens.Simple<Map<K, V>, V> valueAt(K k, V defaultValue) {
67
70
}
68
71
69
72
/**
70
- * Convenience static factory method for creating a lens that focuses on the keys of a map.
73
+ * A lens that focuses on the keys of a map.
71
74
*
72
75
* @param <K> the key type
73
76
* @param <V> the value type
@@ -84,8 +87,8 @@ public static <K, V> Lens.Simple<Map<K, V>, Set<K>> keys() {
84
87
}
85
88
86
89
/**
87
- * Convenience static factory method for creating a lens that focuses on the values of a map. In the case of
88
- * updating the map, only the entries with a value listed in the update collection of values are kept.
90
+ * A lens that focuses on the values of a map. In the case of updating the map, only the entries with a value listed
91
+ * in the update collection of values are kept.
89
92
*
90
93
* @param <K> the key type
91
94
* @param <V> the value type
@@ -104,8 +107,8 @@ public static <K, V> Lens.Simple<Map<K, V>, Collection<V>> values() {
104
107
}
105
108
106
109
/**
107
- * Convenience static factory method for creating a lens that focuses on the inverse of a map (keys and values
108
- * swapped). In the case of multiple equal values becoming keys, the last one wins.
110
+ * A lens that focuses on the inverse of a map (keys and values swapped). In the case of multiple equal values
111
+ * becoming keys, the last one wins.
109
112
*
110
113
* @param <K> the key type
111
114
* @param <V> the value type
@@ -122,4 +125,27 @@ public static <K, V> Lens.Simple<Map<K, V>, Map<V, K>> inverted() {
122
125
return m ;
123
126
});
124
127
}
128
+
129
+ /**
130
+ * A lens that focuses on a map while mapping its values with the mapping function.
131
+ *
132
+ * @param fn the mapping function
133
+ * @param <K> the key type
134
+ * @param <V> the unfocused map value type
135
+ * @param <V2> the focused map value type
136
+ * @return a lens that focuses on a map while mapping its values
137
+ */
138
+ public static <K , V , V2 > Lens .Simple <Map <K , V >, Map <K , V2 >> mappingValues (Function <? super V , ? extends V2 > fn ) {
139
+ return Lens .simpleLens (m -> m .entrySet ().stream ().collect (toMap (Map .Entry ::getKey , kv -> fn .apply (kv .getValue ()))),
140
+ (s , b ) -> {
141
+ //todo: remove this madness upon arrival of either invertible functions or Iso<V,V2>
142
+ Set <K > retainKeys = Filter .<Map .Entry <K , V >>filter (kv -> eq (fn .apply (kv .getValue ()), b .get (kv .getKey ())))
143
+ .andThen (map (Map .Entry ::getKey ))
144
+ .andThen (toCollection (HashSet ::new ))
145
+ .apply (s .entrySet ());
146
+ Map <K , V > copy = new HashMap <>(s );
147
+ copy .keySet ().retainAll (retainKeys );
148
+ return copy ;
149
+ });
150
+ }
125
151
}
0 commit comments