Skip to content

toMap() function is missing; would like to offer my implementation #71

Description

@gearifysoftware

Hello,

Since this states it supports the map stl container type, and if this is supposed to mimic C# Linq, then I think its reasonable to expect that there should be a ToDictionary() equivalent (toMap() for C++/boolinq).

I don't fully understand C++ templates (does anyone, really?) but I was able to put together a basic implementation. The implementation takes two selector functions, one for key, another for value, just like Linq's ToDictionary( ) in C#.

Implementation code:

#include <map>   //remember to include map

template<typename F, typename _FRet = typename priv::result_of<F(T)>::type,
              typename G, typename _GRet = typename priv::result_of<G(T)>::type>
     std::map<_FRet, _GRet> toMap(F keySelector, G valueSelector) const
     {
         auto keys = select_i([keySelector](T value, int /*index*/)
         { 
             return keySelector(value); 
         }).toStdVector();

         auto values = select_i([valueSelector](T value, int /*index*/)
         { 
             return valueSelector(value); }
         ).toStdVector();
         
         std::map< _FRet, _GRet> toReturn;
          
         for (int i = 0; i < keys.size(); i++)
         {
             toReturn[keys[i]] = values[i];
         }

         return toReturn;
     }

One key difference (pun intended) is that this version does not throw an exception if they keys are not distinct, it just overwrites duplicate values in the loop. I do not need such a behavior for my purposes but it could be modified to mimic this as well.

Example usage:

        struct Tax {
	        std::string name;
	        int amount_1;
	        int amount_2;
        
	        bool operator ==(const Tax& tax) const {
		        return name == tax.name
			        && amount_1 == tax.amount_1
			        && amount_2 == tax.amount_2;
	        }
        };

	std::vector<Tax> taxes = {
	   {"tax 1", 1, 1},
	   {"tax 2", 1, 1},
	   {"tax 1", 2, 2},
	   {"tax 3", 3, 3},
	   {"tax 1", 4, 4},
	};
 
        auto resultMap = from(taxes)
        .groupBy([](const Tax& a) {return a.name; })
        .select([](const auto& pair) { // use of auto here needs c++14
          return Tax{
			          pair.first,
			          pair.second.sum([](const Tax& a) {return a.amount_1; }),
			          pair.second.sum([](const Tax& a) {return a.amount_2; })
          };
	}).toMap( [](const Tax& a) {return a.name; }, //key selector
	                [](const Tax& a) {return a.amount_1; });//value selector
        
        int value = resultMap["tax 1"];
        cout << value;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions