find largest value of a tuple element c++

Viewed 2012

I was wondering if there is a succinct way of finding the max value of one of the elements in a vector of tuples. e.g. for the following, say I want to find the largest second value of the tuple in the vector of tuples.

vector<tuple<int, int>> foo = { {12,1},{12,5},{5,6} };

The result should be 6.

One way I could do this would be something like:

vector<double> allFoo;
for (int i = 0; i != size(foo); i++) {
    allFoo.emplace_back(get<1>(foo[i]));
}
double maxVal = *max_element(allFoo.begin(), allFoo.end());

I feel though, that because you are essentially iterating over things twice, this could be done much more simply?

My tuple skills are a bit limited and it seems like you should be able to do some kind of max_element directly on foo...

3 Answers

In one pass, with custom comparer:

std::vector<std::tuple<int, int>> foo = { {12,1},{12,5},{5,6} };

const auto less_by_second = [](const auto& lhs, const auto& rhs)
    { return std::get<1>(lhs) < std::get<1>(rhs); };
const double maxVal = std::get<1>(*std::max_element(foo.begin(), foo.end(), less_by_second));

Use max_element with a custom predicate:

auto maxVal = get<1>(*max_element(foo.begin(), foo.end(), 
                      [](auto& l, auto& r) {return get<1>(l) < get<1>(r);}));   

a version with structured bindings:

std::vector<std::tuple<int, int>> tv = { {12, 1}, {13,2}, {11, 1} };

auto [max1, max2] = *max_element(begin(tv), end(tv), [](auto &lhs, auto &rhs) -> int {return std::get<1>(lhs) < std::get<1>(rhs); });

cout << max2 << endl;
Related