Home > front end >  How to randomly pick an item from vector which have x property
How to randomly pick an item from vector which have x property

Time:07-29

I have a vector from struct Student

struct Student::

struct Student{
string name;
float x;
float y;
bool dropped;
};

std::vector<Student> students;

I am looking for a way to randomly pick a vector item in which a special property (in this case dropped value) is true

what is the most efficient way to do so?

CodePudding user response:

You could create a helper function that first collects iterators to all elements matching a unary predicate and then selects one of those at random.

It could look like this:

#include <random>

std::mt19937& prng() {
    static std::mt19937 instance(std::random_device{}());
    return instance;
}

template <class It, class UnaryPredicate>
It get_random(It first, It last, UnaryPredicate&& pred) {
    if (first == last) return last; // empty range

    std::vector<It> iters; // to store iterators to elements matching pred

    for (; first != last;   first) {
        if (pred(*first)) iters.push_back(first); // matching pred, store it
    }

    // create a uniform integer distribution for [0, iters.size())
    std::uniform_int_distribution<size_t> dist(0, iters.size() - 1);

    // select a random iterator and return it:
    return iters[dist(prng())];
}

It would then be used like this:

auto it = get_random(students.begin(), students.end(),
                     [](Student& s) { return s.dropped; });

std::cout << "picked " << it->name << '\n';

Demo

  •  Tags:  
  • c 11
  • Related