You can use std::accumulate
, paired with custom functors:
#include <iostream>
#include <vector>
#include <numeric>
#include <limits>
#include <algorithm>
struct average_and_min {
int sum = 0;
int min = std::numeric_limits<int>::max();
std::size_t num_of_elements = 0;
int get_sum() {
return sum;
}
double get_average() {
return static_cast<double>(sum) / num_of_elements;
}
int get_min() {
return min;
}
};
int main() {
std::vector<int> vec = {1, 2, 5, 4, 4, 2, 4};
auto func_accumulate = [](average_and_min acc, int value) {
return average_and_min{acc.sum + value, std::min(acc.min, value), acc.num_of_elements + 1};
};
auto data = std::accumulate(vec.cbegin(), vec.cend(), average_and_min{}, func_accumulate);
std::cout << "avg: " << data.get_average() << '\n'
<< "min: " << data.get_min() << '\n';
}
EDIT:
As @Caleth suggested in the comments, it might be a good idea not to use lambdas to combine your struct and the value - you can overload operator +
inside average_and_min
like so:
average_and_min operator + (int value) {
return average_and_min{sum + value, std::min(min, value), num_of_elements + 1};
}
and the line
auto data = std::accumulate(vec.cbegin(), vec.cend(), average_and_min{}, func_accumulate);
can now become
auto data = std::accumulate(vec.cbegin(), vec.cend(), average_and_min{});