As the second value is sorted, you can perform a binary search. (If it weren't sorted, you could just use std::find_if
which is linear)
To perform binary search you need to use std::lower_bound
which is tricky. You need to provide a functor to tell it how your vector is sorted, in this case by the second value. If it finds the value, it returns an iterator to it. If it doesn't find the value, it either returns an iterator to another value or the end iterator. The if statement checks for end iterator first as it is invalid to dereference the end iterator.
This won't work if your vector isn't sorted by the second value. You may want to assert that it is sorted first, to avoid accidents.
The functor provided to std::lower_bound
only needs the key type for the second parameter (when searching, the first pair value doesn't form the key). But to assert it is sorted, both parameters must be the type stored in the vector.
std::vector<std::pair<T1, T2>> data;
T2 find_val;
// check the vector is sorted properly
assert(std::is_sorted(data.begin(), data.end(), [](const std::pair<T1, T2>& left, const std::pair<T1, T2>& right){ return left.second < right.second; }));
// attempt to find our value
auto find_it = std::lower_bound(data.begin(), data.end(), find_val, [](const std::pair<T1, T2>& left, const T2& right){ return left.second < right; });
// check it's not the end iterator and it actually points to our value
if (find_it != data.end() && find_it->second == find_val)
{
// found it!
auto& retrieve_val = find_it->first;
}
else
{
// not found
}
Here is an example using std::find_if
which is a linear search but doesn't care if the vector is sorted.
auto find_it = std::find_if(data.begin(), data.end(), [&find_val](const std::pair<T1, T2>& val){ return val.second == find_val; });
if (find_it != data.end())
{
// found it!
auto& retrieve_val = find_it->first;
}
else
{
// not found
}