Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way to do a C# LINQ Where/Select in C++?

Tags:

c++

c#

linq

In C#, if I have a List of objects (e.g. List myObjectList), I can get a subset of that list via:

anotherMyObjectList = myObjectList.Where(x => x.isSomething()).Select(x => x).ToList();

Assuming I don't want to use a 3rd party C++ LINQ library (only standard library and maybe boost), what's the best way to do this in C++? It would be easy to write a function for each instance where I want to do this, but it would be better to know what framework exists to perform this type of operation.

If the answer is different in C++98, C++0x or C++11, it would be good to know the differences.

like image 958
Jeff Avatar asked Aug 31 '13 17:08

Jeff


3 Answers

In C++11, using boost you can do something like this:

// assumming myObjectList is a vector of someObj type
std::vector<someObj> myObjectList = { ... };
auto result = myObjectList | boost::adaptors::filtered([](const someObj& x) { return x.isSomething(); });
std::vector<someObj> anotherMyObjectList(boost::begin(result), boost::end(result));
like image 110
Paul Fultz II Avatar answered Oct 11 '22 14:10

Paul Fultz II


You can use "ccplinq" :

using namespace cpplinq;
int ints[] = {3,1,4,1,5,9,2,6,5,4};
auto result = from_array (ints)
    >> where ([](int i) {return i/2 == 0;}) 
    >> select ([](int i) {std::stringstream s; s << i; return s.str();})
    >> to_list ();
like image 35
Ehsan Keramat Avatar answered Oct 11 '22 15:10

Ehsan Keramat


You can use std::copy_if() to create a subset of a container:

#include <algorithm>
#include <iterator>
#include <list>

std::list<object> myObjectList, anotherMyObjectList;

// fill myObjectList somehow

std::copy_if(cbegin(myObjectList),
             cend(myObjectList),
             std::back_inserter(anotherMyObjectList),
             [](const object& o) { return o.IsSomething(); }); 

or if you're using C++98/03:

#include <algorithm>
#include <iterator>
#include <list>

std::list<object> myObjectList, anotherMyObjectList;

// fill myObjectList somehow

struct is_something {
    bool operator()(const object&) {
        return object.IsSomething();
    }
};

std::copy_if(myObjectList.cbegin()
             myObjectList.cend(),
             std::back_inserter(anotherMyObjectList),
             is_something());
like image 33
Ferruccio Avatar answered Oct 11 '22 14:10

Ferruccio