Suppose I have a vector<int> myVec;
and I want to convert it to a set, I can have a one liner-
set<int> mySet(myVec.begin(), myVec.end());
This is something that can be found easily.
Now I have vector<pair<int, int>>
, and I want to obtain the set of the second values in each of the pairs. How should I use a set constructor to achieve this? Is it possible?
Assuming I have C++11, C++14, C++17.
Also, I would appreciate if I can get some information about how to do similar tweaks in a general sense for different containers.
Asking for one-liner in this case inevitably leads to a solution with range-v3:
#include <range/v3/view/map.hpp>
const std::vector<std::pair<int, int>> myVec{{1, 10}, {2, 20} , {3, 30}};
const std::set<int> mySet = myVec | ranges::view::values;
And a similar approach with Boost range¹:
#include <boost/range/adaptor/map.hpp>
using boost::adaptors::map_values;
const auto mySet = boost::copy_range<std::set<int>>(myVec | map_values);
You might consider this approach the simplest, however (no libraries, but C++17 required):
for (const auto& [first, second] : myVec)
mySet.insert(second);
¹ Thanks to @Caleth for suggesting an improvement in the comments.
This almost-one-liner should work for you:
#include <algorithm>
#include <iterator>
#include <iostream>
#include <set>
#include <utility>
#include <vector>
int main()
{
std::vector<std::pair<int, int>> myVec = { {1, 2}, {3, 4} };
std::set<int> mySet;
std::transform(myVec.begin(), myVec.end(), std::inserter(mySet, mySet.begin()),
[](const std::pair<int, int>& elem) { return elem.second; });
for (int value : mySet)
{
std::cout << value << std::endl;
}
return 0;
}
Output:
2
4
The most C++y way to do this is probably to define a custom iterator type which produces only the second value.
You can use very similar code as that for a more common query, which is to take the values from a map: iterator adapter to iterate just the values in a map?
Or, you know, just write a loop. Nothing wrong with that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With