1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
#include <iostream>
#include <map>
#include <functional>
#include <tuple>
// return a map of count of occurrences of the mapped_type in the original map
// the keys are wrapped references: to avoid (a potentially expensive) copy of the mapped values
// because of the above, use the map returned by this function immediately
// (before any modifications are made to the original map)
template < typename KEY_TYPE, typename MAPPED_TYPE >
std::map< std::reference_wrapper<const MAPPED_TYPE>, std::size_t > get_mapped_counts( const std::map<KEY_TYPE,MAPPED_TYPE>& map )
{
std::map< std::reference_wrapper<const MAPPED_TYPE>, std::size_t > counts ;
for( const auto& pair : map ) ++counts[ pair.second ] ;
return counts ;
}
struct date
{
int d = 1 ;
int m = 1 ;
int y = 1970 ;
};
// make date LessThanComparable (we want to use it as the key type of a map)
bool operator< ( const date& a, const date& b )
{ return std::make_tuple( a.y, a.m, a.d ) < std::make_tuple( b.y, b.m, b.d ) ; }
int main()
{
const std::map< int, date > my_map
{
{ 1, { 1, 1, 2001 } },
{ 7, { 20, 4, 2019 } },
{ 10, { 1, 1, 2001 } },
{ 8, { 1, 1, 2001 } },
{ 6, { 20, 4, 2019 } },
{ 5, { 5, 5, 2555 } },
{ 2, { 20, 4, 2019 } },
{ 4, { 1, 1, 2001 } },
{ 9, { 5, 5, 2555 } },
{ 3, { 1, 1, 2001 } },
};
const auto counts = get_mapped_counts(my_map) ;
for( const auto& pair : counts )
{
const date& dt = pair.first; // get the wrapped date
std::cout << "date " << dt.d << '/' << dt.m << '/' << dt.y
<< " occurs " << pair.second << " times.\n" ;
}
}
|