2013-09-05 9 views
5

निम्नलिखित पर विचार करें:C++ एसटीडी एक सूची प्रतिलिपि बनाई जा रही मैप करने के लिए

struct A 
{ 
    int i; 
    double d; 
    std::string s; 
}; 

std::list<A> list_A; 

मैं एक नक्शा करने के लिए list_A के सभी तत्वों को कॉपी करना चाहते हैं ऐसी है कि नक्शे में हर जोड़ी के रूप में list_A से एक तत्व शामिल होंगे कुंजी और इसकी स्ट्रिंग s कुंजी के रूप में। क्या ऐसा करने का कोई तरीका है जो सूची के माध्यम से लूपिंग से अधिक सुरुचिपूर्ण है और मानचित्र के लिए कुंजी के रूप में प्रत्येक स्ट्रिंग के साथ प्रत्येक तत्व डालें?

+5

मेरे लिए लूपिंग सबसे अच्छा पठनीय और सबसे सहायक समाधान है। –

+1

आप ['std :: transform'] (http://en.cppreference.com/w/cpp/algorithm/transform) के साथ कुछ कर सकते हैं। – juanchopanza

+0

आप मानक 'के लिए' या 'लम्बाई के लिए' आधारित-मानक का उपयोग कर सकते हैं। यदि इसके बजाय आप एक मानक लाइब्रेरी एल्गोरिदम का उपयोग करते हैं तो आप उसी लूप बॉडी को लिखेंगे और एल्गोरिदम को पास करने के लिए इसे फ़ंक्शन ऑब्जेक्ट या लैम्ब्डा में पैकेजिंग करेंगे। निजी तौर पर, इस सरल के लिए मुझे लगता है कि 'लूप के लिए 'श्रेणी-आधारित" बेहतर "है। – Blastfurnace

उत्तर

6

यह आपको transform कैसे उपयोग करने के लिए के विचार मिलना चाहिए:

std::pair<std::string, A> pairify(const A& a) { return std::make_pair(a.s, a); } 

std::transform(list.begin(), list.end(), std::inserter(map, map.end()), pairify); 

reason to use the inserter है:

एक डालने interator उत्पादन iterator एक विशेष प्रकार का एल्गोरिदम अनुमति देने के लिए डिज़ाइन किया गया है जो आम तौर पर कंटेनर में किसी विशिष्ट स्थिति पर नए तत्वों को स्वचालित रूप से डालने के लिए तत्वों (जैसे प्रतिलिपि) को ओवरराइट करता है।

+0

और यह ठीक काम करता है :) –

+0

I पता है कि मैंने दक्षता के बारे में नहीं पूछा था, लेकिन मैं curios हालांकि: क्या यह तरीका सभी तत्वों के माध्यम से लूपिंग और नक्शे में डालने से भी अधिक कुशल है? – Subway

1

क्षमा करें बिना किसी विवरण के आखिरी बार उत्तर दिया गया, यहां एक संकलित कोड है।

struct A 
{ 
    int i; 
    double d; 
    std::string s; 
}; 

std::list<A> list_A; 

std::pair<std::string, A> convert(const A &x) { 
    return make_pair(x.s,x); 
} 

int main() { 

    std::map<std::string,A> out; 

    std::transform(list_A.begin(), list_A.end(), std::inserter(out,out.end()),convert); 

} 
+0

नहीं ... सबसे पहले, मानचित्र को दो टेम्पलेट पैरामीटर की आवश्यकता होती है और दूसरा आप सूची के समान आकार के लिए मानचित्र प्रारंभ नहीं कर सकते हैं। – LarryPel

+0

इसके अलावा, ट्रांसफॉर्म कुछ ऐसा करेगा: * map_iterator = functionToCopyStructToList(); और आप इस तरह के मैप इटरेटर को "असाइन नहीं कर सकते" ... वह कोड – LarryPel

+0

संकलित नहीं करेगा, आप दोनों सही हैं, मैं केवल सभी विवरणों के बिना पहली बार रूपरेखा दे रहा था – jayadev

0

मैं एक set में संग्रहीत हो सकता है: इस तरह से वहाँ के नक्शे में डेटा दोहराव नहीं होगा (रों ही):

struct A 
{ 
    bool operator < (const A& r_) const { return (s < r_.s); } 
    int i; 
    double d; 
    std::string s; 
}; 

std::list<A> list_A; 
std::set<A> set_A; 

for (std::list<A>::const_iterator itr = list_A.begin(); itr != list_A.end(); ++itr) { 
    if (! set_A.insert(*itr).second) { 
     // Handle duplicated elements 
    } 
} 

मैं पाश रख सकते हैं: इस तरह से आप को संभाल सकता डुप्लिकेट तत्व सही ढंग से।

0

आप सी ++ 11 तुम कब्जा करने के साथ लैम्ब्डा समारोह का उपयोग कर सकते का उपयोग करते हैं:

std::map<std::string, A> m; 
std::list<A> l; 
std::for_each(l.begin(), l.end(), 
       [&](const A& a) { 
        m.insert(std::make_pair(a.s, a)); 
       }); 
4

मैं मानक पुस्तकालय एल्गोरिदम और lambdas प्यार, लेकिन यह नहीं मिलता है बहुत सरल से:

for (const A& value : list_A) { 
    map_A.insert(std::make_pair(value.s, value)); 
} 

अन्य विधियां इस कोड के बराबर कर रही हैं और यह लूप पठनीय और तेज़ है।

+0

मुझे लगता है कि यह आदमी सादगी के लिए नहीं है :)। –

संबंधित मुद्दे