diff --git a/Documentation/algorithms.md b/Documentation/algorithms.md
index dd7e0f8..7b12d5c 100644
--- a/Documentation/algorithms.md
+++ b/Documentation/algorithms.md
@@ -8,6 +8,7 @@ Modifying algorithms
- filter
- transform / transformed
- filtered_transformed
+- transformed_map_values
- reverse
- sort / sorted
- sort_by / sorted_by
@@ -199,6 +200,37 @@ auto result = kdalgorithms::filtered_transformed(structVec, &Struct::sumPairs,
auto result = kdalgorithms::filtered_transformed(intVector, squareItem, isOdd);
```
+transformed_map_values
+-----------------------------------------------------------
+Another special case of transforming is to only transform the values in a map, ie. not the keys.
+
+```
+std::map map{{1, 2}, {2, 3}, {3, 4}};
+auto toString = [](int i) { return std::to_string(i); };
+auto result = kdalgorithms::transformed_map_values(map, toString);
+// result is now std::map{{1, "2"}, {2, "3"}, {3, "4"}};
+```
+
+A more involving example would be this:
+
+```
+struct TimeOnProjects
+{
+ int projectID;
+ int hours;
+};
+using TimeList = QList;
+
+TimeList timeOnProjects{{1, 10}, {2, 20}, {1, 30}, {3, 40}, {2, 12}};
+
+auto map = kdalgorithms::multi_partitioned(timeOnProjects, &TimeOnProjects::projectID);
+auto sumList = [](const TimeList &list) {
+ return kdalgorithms::sum(list, &TimeOnProjects::hours);
+};
+auto result = kdalgorithms::transformed_map_values(map, sumList);
+// result is std::map{{1, 40}, {2, 32}, {3, 40}};
+```
+
reverse / reversed
-----------------------------------------
diff --git a/src/kdalgorithms_bits/transform.h b/src/kdalgorithms_bits/transform.h
index 1f1cfb3..30c9afc 100644
--- a/src/kdalgorithms_bits/transform.h
+++ b/src/kdalgorithms_bits/transform.h
@@ -239,4 +239,48 @@ auto filtered_transformed(InputContainer &&input, Transform &&transform,
detail::to_function_object(std::forward(unaryPredicate)));
}
+namespace detail {
+ template
+ auto transformed_map_values(Map &&input, Transform &&transform)
+ {
+ return transformed(
+ std::forward