Home > Software engineering >  Iterate through container of structs by specific member
Iterate through container of structs by specific member

Time:09-24

I have a function

template<typename I> double mean(I begin, I end)
{
    double s = 0;
    size_t n = 0;
    while(begin != end)
    {
        s  = *begin  ;
          n;
    }
    
    return s / n;
}

and a vector of structs T:

struct T
{
    double a;
    double b;
};
vector<T> v;

Is there an elegant way to compute mean of all a members of structs in v? Some way to wrap vector<T>::iterator to iterator that extracts a member?

CodePudding user response:

You would need to tell mean() which member of T to look at. You can use a pointer-to-data-member for that, eg:

template<typename Iter, typename T>
double mean(Iter begin, Iter end, double (T::*member))
{
    double s = 0;
    size_t n = 0;
    while (begin != end)
    {
        s  = (*begin  ).*member;
          n;
    }
    
    return s / n;
}

struct T
{
    double a;
    double b;
};

vector<T> v;
// fill v...
double m = mean(v.begin(), v.end(), &T::a/*or b*/);

Online Demo

You could take this further by getting rid of your manual loop and use std::accumulate() instead, eg:

#include <numeric>
 
template<typename Iter, typename T>
double mean(Iter begin, Iter end, double (T::*member))
{
    size_t n = 0;
    double s = std::accumulate(begin, end, 0.0,
        [&](double acc, const T &t){   n; return acc   t.*member; }
    );
    return s / n;
}

Online Demo

In which case, you could just get rid of mean() altogether:

#include <numeric>

vector<T> v;
// fill v...
double m = accumulate(v.begin(), v.end(), 0.0,
    [](double acc, const T &t){ return acc   t.a/*or b*/; }
) / v.size();

Online demo

  • Related