How to get min or max element in a vector of structures in c++, based on some field in the structure?
For example:
struct Size {
int width, height;
}
vector<Size> sizes;
...
vector<Size> sortedByWidths(sizes);
vector<Size> sortedByHeights(sizes);
sort(sortedByWidths.begin(), sortedByWidths.end(),
[](Size s1, Size s2) {return s1.width < s2.width;});
sort(sortedByHeights.begin(), sortedByHeights.end(),
[](Size s1, Size s2) {return s1.height< s2.height;});
Use std::min/std::max/std::minmax _element
with comparator.
http://en.cppreference.com/w/cpp/algorithm/min_element
In C++11, you can use the std::minmax_element() standard function, which (given a pair of iterators) and possibly a custom comparator (that would allow you to define the field on which the ordering is based), will return you an iterator to the minimum and an iterator to the maximum element, packed in an std::pair
.
So for instance:
#include <algorithm> // For std::minmax_element
#include <tuple> // For std::tie
#include <vector> // For std::vector
#include <iterator> // For global begin() and end()
std::vector<Size> sizes = { {4, 1}, {2, 3}, {1, 2} };
decltype(sizes)::iterator minEl, maxEl;
std::tie(minEl, maxEl) = std::minmax_element(begin(sizes), end(sizes),
[] (Size const& s1, Size const& s2)
{
return s1.width < s2.width;
});
Here is a live example.
Solution using std::minmax_element with lambda expression:
#include <iostream>
#include <vector>
struct Size {
int width, height;
};
int main()
{
std::vector<Size> sizes;
sizes.push_back({4,1});
sizes.push_back({2,3});
sizes.push_back({1,2});
auto minmax_widths = std::minmax_element(sizes.begin(), sizes.end(),
[] (Size const& lhs, Size const& rhs) {return lhs.width < rhs.width;});
auto minmax_heights = std::minmax_element(sizes.begin(), sizes.end(),
[] (Size const& lhs, Size const& rhs) {return lhs.height < rhs.height;});
std::cout << "Minimum (based on width): " << minmax_widths.first->width << std::endl;
std::cout << "Maximum (based on width): " << minmax_widths.second->width << std::endl;
std::cout << "Minimum (based on height): " << minmax_heights.first->height << std::endl;
std::cout << "Maximum (based on height): " << minmax_heights.second->height << std::endl;
}
You can use std::min_element and std::max_element with a suitable functor:
bool cmp(const Size& lhs, const Size& rhs)
{
return lhs.width < rhs.width;
}
then
auto min_it = std::min_element(sizes.begin(), sizes.end(), cmp);
auto max_it = std::max_element(sizes.begin(), sizes.end(), cmp);
In C++11 you can replace cmp
with a lambda expression.
See also: std::minmax_element