আমি কীভাবে সি ++ এর মানচিত্রে লুপ করতে পারি?


292

আমি std::mapসি ++ এ কীভাবে লুপ করব ? আমার মানচিত্রটি হিসাবে সংজ্ঞায়িত করা হয়েছে:

std::map< std::string, std::map<std::string, std::string> >

উদাহরণস্বরূপ, উপরের ধারকটি এই জাতীয় ডেটা ধারণ করে:

m["name1"]["value1"] = "data1";
m["name1"]["value2"] = "data2";
m["name2"]["value1"] = "data1";
m["name2"]["value2"] = "data2";
m["name3"]["value1"] = "data1";
m["name3"]["value2"] = "data2";

আমি কীভাবে এই মানচিত্রটি লুপ করতে এবং বিভিন্ন মানগুলিতে অ্যাক্সেস করতে পারি?


25
আপনি আধুনিক সি ++ এর জন্য দাঙ্গার উত্তর গ্রহণ করতে বিবেচনা করতে পারেন, গুগলদের জন্য এটি করুন।
সেরজিও বাসুরকো

পুরোপুরি নিশ্চিত নয় যে মানচিত্রের মানচিত্রটি একটি ন্যূনতম, সম্পূর্ণ, যাচাইযোগ্য উদাহরণ হবে তবে পয়েন্টটি তৈরি হয়েছে!
ডেভিডহুড

3
আপনি যদি বিজ্ঞপ্তিটি মিস করেন তবে আমাকে চকলেপ্ল্যান্টের মন্তব্যটি পুনরাবৃত্তি করতে দিন: আপনি আধুনিক সি ++ এর জন্য দাঙ্গার উত্তরটি গ্রহণ করার কথা বিবেচনা করতে পারেন, গুগলদের জন্য এটি করুন।
noɥʇʎԀʎzɐɹƆ

কুকুরছানাটির উত্তর আরও বহুমুখী, তবে গুগলরা দাঙ্গার উত্তর আরও বেশি চান বলে আপভোটের সংখ্যা দিয়ে বিচার করে।
সৈনিক দাইথ

উত্তর:


563

পুরানো প্রশ্ন তবে বাকী উত্তরগুলি C ++ 11 হিসাবে পুরানো হয়েছে - আপনি লুপের উপর ভিত্তি করে একটি রেঞ্জ ব্যবহার করতে পারেন এবং কেবল:

std::map<std::string, std::map<std::string, std::string>> mymap;

for(auto const &ent1 : mymap) {
  // ent1.first is the first key
  for(auto const &ent2 : ent1.second) {
    // ent2.first is the second key
    // ent2.second is the data
  }
}

এটি পূর্ববর্তী সংস্করণগুলির তুলনায় অনেক পরিষ্কার হওয়া উচিত এবং অপ্রয়োজনীয় অনুলিপিগুলি এড়ানো উচিত।

কিছু রেফারেন্স ভেরিয়েবলের সুস্পষ্ট সংজ্ঞা দিয়ে মন্তব্যগুলি প্রতিস্থাপনের পক্ষে (যা অব্যবহৃত হলে অপ্টিমাইজড হয়ে যায়):

for(auto const &ent1 : mymap) {
  auto const &outer_key = ent1.first;
  auto const &inner_map = ent1.second;
  for(auto const &ent2 : inner_map) {
    auto const &inner_key   = ent2.first;
    auto const &inner_value = ent2.second;
  }
}

13
উত্তরগুলি প্রাসঙ্গিক রাখার জন্য প্রপসগুলি - আমি কেবল চাই যে এটি শীর্ষে আরও এগিয়ে যেতে পারে। সম্ভবত এটি গ্রহণযোগ্য উত্তরে সম্পাদনা করা উপযুক্ত হবে? (এটি আমরা টেক্সএক্সএক্সএক্সে করি তবে এসও আলাদা সংস্কৃতি))
সান অলরেড

2
কেবল একটি তাত্ক্ষণিক প্রশ্ন, আপনার লেখার constপরে সিদ্ধান্তের কোনও প্রাসঙ্গিকতা আছে autoকি? এটি কি নিখুঁত নান্দনিক?
পারহাম

6
@ পারহাম কনস্ট একটি নির্দিষ্ট ধরণের আগে বা তার পরে পছন্দ করা বিষয়, তবে আমি এটিকে ডানদিকে রাখা পছন্দ করি কারণ এটি পয়েন্টার ব্যবহার করা হচ্ছে এমন পরিস্থিতিতে এটি আরও স্পষ্ট করে তোলে; উদাহরণস্বরূপ উভয় ব্যবহার করার সময় int const *xএবং int *const xআপনি এটিকে int const *const xএটি থেকে আরও পরিষ্কার আইএমও হিসাবে লিখতে পারেন const int *const x। তবে এটি কেবল বাম থেকে ডানে পার্স করা হয়েছে যাতে প্রভাবটি একই। এই প্রশ্নের উত্তর দেখুন: stackoverflow.com/questions/5503352/const-before-or-const- after
দাঙ্গা

2
অটো কনস্ট & এনটি 2 এ & এর অর্থ কী?
ট্যানার গ্রীষ্মকাল

5
@ ট্যানারস্মার্স কারণ মান দ্বারা অ্যাক্সেস প্রতিটি উপাদান অনুলিপি অদক্ষতা যোগ করবে; অতিরিক্ত হিসাবে আপনি যদি বিষয়বস্তুগুলি সংশোধন করতে চান তবে আপনাকে মানটির পরিবর্তে রেফারেন্সগুলি (বা পয়েন্টার) দ্বারা উপাদানগুলি অ্যাক্সেস করতে হবে।
দাঙ্গা

308

আপনি একটি পুনরায় ব্যবহারকারীর ব্যবহার করতে পারেন।

typedef std::map<std::string, std::map<std::string, std::string>>::iterator it_type;
for(it_type iterator = m.begin(); iterator != m.end(); iterator++) {
    // iterator->first = key
    // iterator->second = value
    // Repeat if you also want to iterate through the second map.
}

10
তিনি মানচিত্রটি সংশোধন করতে না চাইলে কনস্ট_টিরেটর ব্যবহার করা আরও ভাল।
মাইকেল অ্যারন সাফিয়ান

28
এটি পুনরুক্তিকর তুলনায় ++ পুনরুক্তি করা ++ এর চেয়ে কার্যকর কারণ এটি বৃদ্ধি করার সময় একটি অপ্রয়োজনীয় অনুলিপি এড়িয়ে চলে।
গেম_অভারচার

19
অটো ব্যবহার করে সি ++ 11 এর জন্য লুপটি সহজতর করে:for(auto iterator = m.begin(); iterator != m.end(); iterator++)
জেরার্ড

127
এটি সি ++ 11 এর জন্য বেশ পুরানো। কেবল (অটো ইটার: মাইম্যাপ) এর জন্য ব্যবহার করুন
বেনামে সত্তা

37
সি ++ 11 এর জন্য, আপনার সম্ভাব্য অনুলিপি এড়াতে আপনার (অটো এবং ইটার: মাইম্যাপ) ব্যবহার করা উচিত।
দেব_নাট

60
for(std::map<std::string, std::map<std::string, std::string> >::iterator outer_iter=map.begin(); outer_iter!=map.end(); ++outer_iter) {
    for(std::map<std::string, std::string>::iterator inner_iter=outer_iter->second.begin(); inner_iter!=outer_iter->second.end(); ++inner_iter) {
        std::cout << inner_iter->second << std::endl;
    }
}

বা সি ++ 0x এ আরও ভাল:

for(auto outer_iter=map.begin(); outer_iter!=map.end(); ++outer_iter) {
    for(auto inner_iter=outer_iter->second.begin(); inner_iter!=outer_iter->second.end(); ++inner_iter) {
        std::cout << inner_iter->second << std::endl;
    }
}

2
আপনার অটো এবং ব্যবহার করা উচিত, বা যদি আপনি মানচিত্রটি সংশোধন না করেন তবে এমনকি অটো ও কনস্ট্রেট করা উচিত। তদতিরিক্ত, অ-সদস্য প্রারম্ভিক () এবং শেষ (), অর্থাৎ (কনট অটো এবং ইটার = আরম্ভ (মানচিত্র); ...) এর জন্য পছন্দ করুন।
এলা 782

13
বা এমনকি আরও সহজ: জন্য (কনট অটো এবং উপাদান: মানচিত্র) কোট << এলিমেন্ট.সেকেন্ড;
এলা 782

26

সি ++ 17 (বা তারপরে) দিয়ে আপনি "স্ট্রাকচার্ড বাইন্ডিংস" বৈশিষ্ট্যটি ব্যবহার করতে পারেন, যা আপনাকে একক টুপল / জুড়ি ব্যবহার করে বিভিন্ন নামের সাথে একাধিক ভেরিয়েবল সংজ্ঞায়িত করতে দেয়। উদাহরণ:

for (const auto& [name, description] : planet_descriptions) {
    std::cout << "Planet " << name << ":\n" << description << "\n\n";
}

মূল প্রস্তাব (উজ্জ্বল জ্যোতিষ্কের বিয়ারনে স্ট্রোভস্ট্রুপের, ঔষধি Sutter এবং গ্যাব্রিয়েল dos Reis দ্বারা) পড়তে মজা (এবং প্রস্তাবিত সিনট্যাক্স আরও বেশি ধারণাসম্পন্ন এই প্রোগ্রামটিতে হয়); এছাড়াও আছে মান জন্য প্রস্তাবিত বাক্যে কথন যা পড়তে বিরক্তিকর কিন্তু আসলে যাব কাছাকাছি হয়।


2
এটি এত সুন্দর যে সি ++ 17 এখনও "সেখানে" না থাকা সত্ত্বেও আমাকে ভোট দেওয়া দরকার। ম্যান, তারা পরিষ্কার এবং নিরাপদ কোড লেখার পক্ষে আরও সহজ করে সি -++ কে সত্যই পুনরুজ্জীবিত করছে।
জোনাস

24

এরকম কিছু করুন:

typedef std::map<std::string, std::string> InnerMap;
typedef std::map<std::string, InnerMap> OuterMap;

Outermap mm;

...//set the initial values

for (OuterMap::iterator i = mm.begin(); i != mm.end(); ++i) {
    InnerMap &im = i->second;
    for (InnerMap::iterator ii = im.begin(); ii != im.end(); ++ii) {
        std::cout << "map[" 
                  << i->first 
                  << "][" 
                  << ii->first 
                  << "] =" 
                  << ii->second 
                  << '\n';
    }
}   

দ্বিতীয়টির জন্য এটিতে ++ ii হওয়া উচিত নয় ++ আমি :)
স্লিপস্ট্রিম

আমি মনে করি শেষে '/ n' একটি '\ n' হওয়া উচিত
কেনিয়াকর্ন কেটসম্বুট

ঠিক আছে আমি তাদের সংজ্ঞায়িত করার পরে সংজ্ঞাগুলি ব্যবহার করতে পারতাম এটি সি ++ 98 এর জন্য একটি ভাল উপায় :) +1
লুডোভিচ জেনোহেট লাগুয়ার্ডেট

12

সি ++ 11:

std::map< std::string, std::map<std::string, std::string> > m;
m["name1"]["value1"] = "data1";
m["name1"]["value2"] = "data2";
m["name2"]["value1"] = "data1";
m["name2"]["value2"] = "data2";
m["name3"]["value1"] = "data1";
m["name3"]["value2"] = "data2";

for (auto i : m)
    for (auto j : i.second)
        cout << i.first.c_str() << ":" << j.first.c_str() << ":" << j.second.c_str() << endl;

আউটপুট:

name1:value1:data1
name1:value2:data2
name2:value1:data1
name2:value2:data2
name3:value1:data1
name3:value2:data2

2
এই উত্তরটি কীভাবে স্ট্যাকওভারফ্লো . com/a/27344958/3658660 থেকে আলাদা ? এটি যে কোনও জায়গায় অনুলিপি তৈরি করছে তা বাদে।
hlscalon

1

std::map< std::string, std::map<std::string, std::string> >::const_iteratorমানচিত্রের কনস্টেবল ব্যবহার করার সময় ব্যবহার করুন ।


1
আপনি জানেন, কখনও কখনও ডান মার্জিনের পিছনে কোড লুকানো ভাল অভ্যাস নয়। আমি এটি নিরাপদ বুঝতে পারি তবে ভাল কোডের দৃষ্টিভঙ্গিটি পুরোপুরি অস্পষ্ট করে তোলে। যাও autoভাই, বা যে ভিম ব্যবহার করে সে কেও যাবে।
লুডোভিচ জেনোহাতে লাগোয়ার্ডেট

0

যেমন ইনপোকলুম তাদের উত্তরে উল্লেখ করেছে , যেহেতু সি ++ 17 আপনি স্ট্রাকচার্ড বাইন্ডিং ঘোষণাগুলিও ব্যবহার করতে পারেন । আমি আরামদায়ক উপায়ে মানচিত্রের মানচিত্রে পুনরাবৃত্তি করার জন্য একটি সম্পূর্ণ সমাধান সরবরাহ করে এটিকে প্রসারিত করতে চাই:

int main() {
    std::map<std::string, std::map<std::string, std::string>> m {
        {"name1", {{"value1", "data1"}, {"value2", "data2"}}},
        {"name2", {{"value1", "data1"}, {"value2", "data2"}}},
        {"name3", {{"value1", "data1"}, {"value2", "data2"}}}
    };

    for (const auto& [k1, v1] : m)
        for (const auto& [k2, v2] : v1)
            std::cout << "m[" << k1 << "][" << k2 << "]=" << v2 << std::endl;

    return 0;
}

দ্রষ্টব্য 1: মানচিত্রটি পূরণ করার জন্য, আমি একটি প্রারম্ভিক তালিকা (যা একটি সি ++ 11 বৈশিষ্ট্য) ব্যবহার করেছে। এটি কখনও কখনও স্থির সূচনাটি কমপ্যাক্ট রাখতে সুবিধাজনক হতে পারে।

দ্রষ্টব্য 2: আপনি যদি mলুপগুলির মধ্যে মানচিত্রটি পরিবর্তন করতে চান তবে আপনাকে constকীওয়ার্ডগুলি মুছে ফেলতে হবে ।

কলিরুতে কোড


0

প্রথম সমাধানটি লুপের জন্য রেঞ্জ_ভিত্তিক ব্যবহার করুন, যেমন:

দ্রষ্টব্য: যখন range_expressionএর ধরণ std::mapতখন একটি range_declarationধরণের হয় std::pair

for ( range_declaration : range_expression )      
  //loop_statement

কোড 1:

typedef std::map<std::string, std::map<std::string, std::string>> StringToStringMap;

StringToStringMap my_map;

for(const auto &pair1 : my_map) 
{
   // Type of pair1 is std::pair<std::string, std::map<std::string, std::string>>
   // pair1.first point to std::string (first key)
   // pair1.second point to std::map<std::string, std::string> (inner map)
   for(const auto &pair2 : pair1.second) 
   {
       // pair2.first is the second(inner) key
       // pair2.second is the value
   }
}

দ্বিতীয় সমাধান:

কোড 2

typedef std::map<std::string, std::string> StringMap;
typedef std::map<std::string, StringMap> StringToStringMap;

StringToStringMap my_map;

for(StringToStringMap::iterator it1 = my_map.begin(); it1 != my_map.end(); it1++)
{
    // it1->first point to first key
    // it2->second point to inner map
    for(StringMap::iterator it2 = it1->second.begin(); it2 != it1->second.end(); it2++)
     {
        // it2->second point to value
        // it2->first point to second(inner) key 
     }
 }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.