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;

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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