2013-03-20 10 views
19

द्वारा ऑब्जेक्ट्स का एक वेक्टर खोजें I ऑब्जेक्ट में किसी सदस्य फ़ील्ड को स्ट्रिंग की तुलना करके - वेक्टर में किसी निश्चित ऑब्जेक्ट की अनुक्रमणिका को ढूंढने का एक अच्छा तरीका जानने का प्रयास कर रहा हूं।ऑब्जेक्ट विशेषता

Like this : find(vector.begin(), vector.end(), [object where obj.getName() == myString]) 

मैंने सफलता के बिना खोज की है - शायद मैं पूरी तरह समझ नहीं पा रहा हूं कि क्या देखना है।

+1

क्या एक ही नाम से एक से अधिक ऑब्जेक्ट हो सकते हैं? क्या आप उन सभी को ढूंढना चाहते हैं? –

उत्तर

36

आप उपयुक्त फिक्सर के साथ std::find_if का उपयोग कर सकते हैं। इस उदाहरण में, एक सी ++ 11 लैम्ब्डा प्रयोग किया जाता है:

std::vector<Type> v = ....; 
std::string myString = ....; 
auto it = find_if(v.begin(), v.end(), [&myString](const Type& obj) {return obj.getName() == myString;}) 

if (it != v.end()) 
{ 
    // found element. it is an iterator to the first matching element. 
    // if you really need the index, you can also get it: 
    auto index = std::distance(v.begin(), it); 
} 

आप कोई सी ++ 11 लैम्ब्डा समर्थन है, तो एक functor काम करेगा:

struct MatchString 
{ 
MatchString(const std::string& s) : s_(s) {} 
bool operator()(const Type& obj) const 
{ 
    return obj.getName() == s_; 
} 
private: 
    const std::string& s_; 
}; 

यहाँ, MatchString एक प्रकार जिसका है उदाहरण एक Type ऑब्जेक्ट के साथ कॉल करने योग्य हैं, और एक बूलियन लौटाते हैं। उदाहरण के लिए,

Type t("Foo"); // assume this means t.getName() is "Foo" 
MatchString m("Foo"); 
bool b = m(t); // b is true 

तो आप एक उदाहरण std::find

std::vector<Type>::iterator it = find_if(v.begin(), v.end(), MatchString(myString)); 
+0

यदि आप एक मजेदार का उपयोग कर रहे हैं तो आपको 'find_if' का उपयोग करने की आवश्यकता है। – Peter

+0

@ पीटर अच्छा पकड़, धन्यवाद! – juanchopanza

5

को लैम्ब्डा और हस्तलिखित Juancho द्वारा प्रयोग किया जाता functor के अलावा पारित कर सकते हैं, तो आप संभावना boost::bind (सी ++ 03 उपयोग करने के लिए) या std::bind (सी ++ 11) और एक साधारण समारोह:

bool isNameOfObj(const std::string& s, const Type& obj) 
{ return obj.getName() == s; } 

//... 
std::vector<Type>::iterator it = find_if(v.begin(), v.end(), 
    boost::bind(&isNameOfObj, myString, boost::placeholders::_1)); 

या, Type एक विधि isName है यदि:

std::vector<Type>::iterator it = find_if(v.begin(), v.end(), 
    boost::bind(&Type::isName, boost::placeholders::_1, myString)); 

यह पूर्णता के लिए है। सी ++ में मैं सी ++ 03 में लैम्बडास पसंद करूंगा, मैं केवल तभी उपयोग करूँगा जब तुलना फ़ंक्शन स्वयं पहले से मौजूद हो। यदि नहीं, तो मजेदार पसंद करते हैं।

पीएस: चूंकि सी ++ 11 में कोई पॉलिमॉर्फिक/टेम्पलेटेड लैम्ब्डा नहीं है, फिर भी यह अभी भी सी ++ 11 में है, उदाहरण के लिए यदि पैरामीटर प्रकार अज्ञात हैं, वर्तनी करना मुश्किल है, या अन्यथा कटौती करना आसान नहीं है।

2

एक साधारण इटरेटर मदद कर सकता है।

typedef std::vector<MyDataType> MyDataTypeList; 
// MyDataType findIt should have been defined and assigned 
MyDataTypeList m_MyObjects; 
//By this time, the push_back() calls should have happened 
MyDataTypeList::iterator itr = m_MyObjects.begin(); 
while (itr != m_MyObjects.end()) 
{ 
    if(m_MyObjects[*itr] == findIt) // any other comparator you may want to use 
    // do what ever you like 
} 
संबंधित मुद्दे