Take a look at the following piece of code:
#include <iostream>
#include <unordered_map>
#include <string>
#include <random>
static std::mt19937_64 rng;
int main()
{
std::unordered_multimap<std::string, std::string> fruits = {
{ "apple", "red" },
{ "apple", "green" },
{ "apple", "blue"},
{ "apple", "white"},
{ "apple" , "black"},
{ "orange", "orange" },
{ "strawberry", "red" }
};
std::random_device rd; // obtain a random number from hardware
std::mt19937 eng(rd()); // seed the generator
for (auto i(0); i < fruits.bucket_count(); ++i) {
auto d = std::distance(fruits.begin(i), fruits.end(i));
if (d > 0) {
std::uniform_int_distribution<> distr(0, d - 1); // define the range
auto r = distr(eng);
std::cout << "random index = " << r << std::endl;
auto elem = fruits.begin(i);
std::advance(elem, r);
std::cout << elem->first << " : " << elem->second << std::endl;
}
}
return 0;
}
Update
A more portable and generic version:
#include <iostream>
#include <unordered_map>
#include <string>
#include <random>
static std::mt19937_64 rng;
// Returns random iterator from an input range.
template<typename LIST_ITERATOR>
LIST_ITERATOR
getRandomIteratorFromRange(LIST_ITERATOR const &begin,
LIST_ITERATOR const &end,
std::mt19937 &random_engine)
{
auto d = std::distance(begin, end);
if(d > 0) {
LIST_ITERATOR out(begin);
std::advance(out, std::uniform_int_distribution<>(0, d - 1).operator()(random_engine));
return out;
}
return end;
}
int main()
{
std::unordered_multimap<std::string, std::string> fruits = {
{"apple", "red"}, { "apple", "green" }, { "apple", "blue" }, { "apple", "white" },
{"apple", "black"}, {"apple", "pink"},{"orange","orange"},{"strawberry", "red"}};
std::random_device rd; // obtain a random number from hardware
std::mt19937 eng(rd()); // seed the generator
for(auto i(0); i < fruits.bucket_count(); ++i) {
auto it = getRandomIteratorFromRange(fruits.begin(i), fruits.end(i), eng);
if(it != fruits.end(i)) std::cout << it->first << " : " << it->second << std::endl;
}
return 0;
}