16

私はc ++を初めて使用し、構造体のベクトルから特定のメンバーデータを持つ構造体を検索する方法を見つけようとしています。

これはベクター内の単純な型で機能することを知っています

std::find(vector.begin(), vector.end(), item) != vector.end()

しかし、次のような構造体があるとしましょう。

struct Friend
{
  string name;
  string number;
  string ID;
};

そして、このようなベクトル:

vector<Friend> friends;

次に、ベクトルは友達でいっぱいになります。

特定の ID を持つ友人を検索し、その詳細を知りたいとしましょう。または、ベクターから特定の構造体を削除します。これを行う簡単な方法はありますか?

4

4 に答える 4

25

This can be done with std::find_if and a search predicate, which can be expressed as a lambda function if you have C++11 (or C++0x) available:

auto pred = [](const Friend & item) {
    return item.ID == 42;
};
std::find_if(std::begin(friends), std::end(friends), pred) != std::end(friends);

To use an ID given as a variable, you have to capture it in the lambda expression (within the [...]):

auto pred = [id](const Friend & item) {
    return item.ID == id;
};
std::find_if(std::begin(friends), std::end(friends), pred) != std::end(friends);

If you don't have C++11 available, you have to define the predicate as a functor (function object). Remy Lebeau's answer uses this approach.

To remove elements matching the criteria as defined by the predicate, use remove_if instead of find_if (the rest of the syntax is the same).

For more algorithms, see the STL <algorithm> reference.

于 2013-01-08T23:39:19.047 に答える
13

を使用しstd::find_if()ます。@leemes と @AndyProwl は、C++11 コンパイラでの使用方法を示しました。ただし、C++11 コンパイラを使用していない場合は、代わりに次のように使用できます。これは、指定されたアイテムの ID をコンストラクターで以前に指定された ID と比較するファンクターを定義します。

class MatchesID
{
    std::string _ID;

public:
    MatchesID(const std::string &ID) : _ID(ID) {}

    bool operator()(const Friend &item) const
    {
        return item.ID == _ID;
    }
};

std::find_if(vector.begin(), vector.end(), MatchesID("TheIDHere")) != vector.end();

プロジェクトに ID を使用する他のクラスがある場合、このファンクターをテンプレート化できます。

template<typename IDType>
class MatchesID
{
    IDType _ID;

public:
    MatchesID(const IDType &ID) : _ID(ID) {}

    template<class ItemType>
    bool operator()(const ItemType &item) const
    {
        return item.ID == _ID;
    }
};

std::find_if(vector.begin(), vector.end(), MatchesID<std::string>("TheIDHere")) != vector.end();
于 2013-01-08T23:43:37.257 に答える
4

std::find_ifファンクター (C++98 を使用している場合) またはラムダ (C++11 を使用している場合) と組み合わせて使用​​できます。

using namespace std;
int ID = 3; // Let's say...
auto it = find_if(begin(vector), end(vector), [=] (Friend const& f) { 
    return (f.ID == ID); 
    });
bool found = (it != end(vector));
于 2013-01-08T23:40:59.820 に答える
2

STL コンテナー内の要素を検索する場合は、std::findまたはstd::find_ifアルゴリズムを使用します C++03 では、std::find に対して operator== をオーバーロードする必要があります

bool operator==(const Friend& lhs, const Friend& rhs)
{
  return lhs.ID == rhs.ID;
}

if (std::find(friends.begin(), friends.end(), item) != friends.end())
{
   // find your friend
}

または C++11 とラムダ:

std::find_if(friends.begin(), friends.end(),  [](Friend& f){ return f.ID == "1"; } );

特定の要素を削除したい場合は、std::remove_ifを使用します

std::remove_if(friends.begin(), friends.end(), 
      [](Friend& f){ return f.ID == "1"; });
于 2013-01-08T23:45:46.507 に答える