vendredi 4 août 2017

How can I elegantly and efficiently group elements of a vector into a map?

I am 'grouping' elements of a vector into a map, is there a more efficient or elegant way to do it, rather than my current apporach? - I feel that it is rather cumbersome codewise, and is optimal in terms of performance.

I am coming from C#, where I normally would solve such situations using as such:

var groupedObservations = observations.GroupBy(o => o.x, o => o.y,o => o.z);

In my current C++, I first sort a vector containing all elements, then using an if-statement I determine when a new group should start and push all subsequent 'equal' elements into that group.

My current code is as followed;

struct Observation { int id; double x,y,z; }
map<int, vector<std::shared_ptr<Observation>>> observations; 

..code that fills observations from csv is omitted ..

map<int,vector<shared_ptr<Observation>>> groupedObservations;


std::sort(observations.begin(), observations.end(), sorting_functor());

int groupId = 0;
double x =0 ,y =0 ,z = 0;
for(shared_ptr<Observation> &observation: observations)
{
    if(!(x == record->x && y== observation->y && z == observation->z))
    {
        groupId++; //coordinates different; new group.
        x = observation->x;
        y = observation->y;
        z = observation->z;

    }
    groupedObservations[groupId].push_back(observation);
}

For completeness, the sorting functor is as follows:

struct sorting_functor
{
    bool operator()(const shared_ptr<Observation> &a, shared_ptr<Observation> &b) const
    {
        return (a->x < b->x) && (a->y < b->y) && (a->z < b->z);
    }
};

Aucun commentaire:

Enregistrer un commentaire