-2

I have a container of objects. I need to implement search by multiple parameters (i.e. users can choose different parameters, and i need to find all objects with those parameters).

Suppose we have a container std::vector<Person> v in which objects with fields are stored: [name, age, profession].

["Lucy", 18, "None"],
["Alex", 25, "Teacher"],
["Lucy", 18, "Student"],
["Lucy", 25, "None"],
["Sofia", 25, "None"].

For example, User needs all the people named Lucy. He gets the result:

["Lucy", 18, "None"],
["Lucy", 18, "Student"],
["Lucy", 25, "None"].

Now users wants to find people with the name Lucy at the age of 18. He will get the result:

["Lucy", 18, "None"],
["Lucy", 18, "Student"].

Now he needs people without a profession at the age of 25.

["Lucy", 25, "None"],
["Sofia", 25, "None"].

The choice of fields by which the search will take place depends on the user's choice! He can choose parameters of search in GUI.

I suppose I need some comparator, but have no idea how it should look like.

template<typename _Comp>
struct Person
{
    std::string name;
    int age;
    std::string profession;
};
  • Perhaps try writing simple methods that can do each of those kinds of lookups separately. Then look at what you've written and see if you can find ways to consolidate them, such as by changing the ways they differ into other kinds of parameters. In the worst case, you can at least bring those into the question here as a more concrete "how do I make these one function?" example. – TheUndeadFish Nov 25 '19 at 20:10
  • 2
    dont let us guess, but show the code instead. What type of container is it? Do you have a struct with members `name`, `age` and `profession`? Once you got those details clear, the rest is just 2-3 lines of code – 463035818_is_not_an_ai Nov 25 '19 at 20:13
  • 1
    [Team up with the person who asked this question](https://stackoverflow.com/q/59037979/4581301). Two heads are better than one. – user4581301 Nov 25 '19 at 20:18
  • There are many LINQ style libraries for C++: https://stackoverflow.com/questions/232222/is-there-a-linq-library-for-c https://stackoverflow.com/questions/10713310/is-there-an-equivalent-in-c-to-linq-with-respect-to-datatables https://stackoverflow.com/questions/1565406/c-linq-like-iterator-operations https://stackoverflow.com/questions/18550800/what-is-the-proper-way-to-do-a-c-sharp-linq-where-select-in-c and others here: https://www.google.com/search?q=linq+c%2B%2B – Jerry Jeremiah Nov 25 '19 at 20:44

1 Answers1

0

I suppose you have a

struct Person {
    std::string name;
    unsigned age;
    std::string profession;
};

and a vector filled with some data

  std::vector<Person> persons{ {"Lucy", 18, "None"},
                             {"Alex", 25, "Teacher"},
                             {"Lucy", 18, "Student"},
                             {"Lucy", 25, "None"},
                             {"Sofia", 25, "None"}};

Just write a loop and check the condition:

std::vector<Person> select_by_name(const std::vector<Person>& persons,const std::string name){
    std::vector<Person> result;
    for (const auto& p : persons) if (p.name == name) result.push_back(p);
    return result;
}

...similar for age and profession...

If you like you can use an algorithm instead:

std::vector<Person> select_by_name2(const std::vector<Person>& persons,const std::string name){
    std::vector<Person> result;
    auto equal_name = [name](const Person& p) { return name == p.name; };
    auto copy_to = std::back_inserter(result);       
    std::copy_if(persons.begin(),persons.end(),copy_to,equal_name);
    return result;
}

This can be generalized to pass the lambda that picks the elements to the functions such that you can use the same function to pick either name, age or profession, eg

template <typename F>
std::vector<Person> select_by(const std::vector<Person>& persons,F f){
    std::vector<Person> result;
    auto copy_to = std::back_inserter(result);       
    std::copy_if(persons.begin(),persons.end(),copy_to,f);
    return result;
}

With the same lambda as above this would be called like this

auto selected = select_by(persons,equal_name);
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185