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(input), + [transform = std::forward(transform)](auto &&pair) { + return std::make_pair(pair.first, transform(pair.second)); + }); + } + + template class Map, typename Key, typename OldValue> + auto map_value(const Map &) -> Map, remove_cvref_t> + { + } +} + +template +auto transformed_map_values(Map &&input, Transform &&transform) +{ + return detail::transformed_map_values(std::forward(input), + std::forward(transform)); +} + +template +auto transformed_map_values(Map &&input, Transform &&transform) +{ + using ValueType = detail::invoke_result_t::mapped_type>; + using ResultMap = decltype(detail::map_value(input)); + return detail::transformed_map_values(std::forward(input), + std::forward(transform)); +} + +template