2011-12-13 153 views
45

unordered_map獲取密鑰和值的列表(作爲vector)的最有效方式是什麼?從unordered_map獲取密鑰和值列表

具體而言,假設有問題的地圖是unordered_map<string, double>。 然後我想獲取密鑰作爲vector<string>,並將其值設爲vector<double>

unordered_map<string, double> um; 

vector<string> vs = um.enum_keys(); 
vector<double> vd = um.enum_values(); 

我可以在地圖上只是重複和收集的結果,但有一個更 有效的方法?如果有一種方法也適用於普通地圖,那麼這將很不錯,因爲我可能會切換到這個方法。

+0

望着標準草案,我沒有看到一個簡單的方法來得到你想要的,但我可能失去了一些東西。你可以說'std :: vector > v(map.begin(),map.end()); '應該給你一個鍵值對的向量。 –

+0

@ keith.layne:我在爲鍵和值尋找單獨的向量。 –

+0

正如我所說,這沒有什麼內置的。見下文。 –

回答

47

好了,在這裏你去:

std::vector<Key> keys; 
keys.reserve(map.size()); 
std::vector<Val> vals; 
vals.reserve(map.size()); 

for(auto kv : map) { 
    keys.push_back(kv.first); 
    vals.push_back(kv.second); 
} 

效率或許可以得到改善,但它是。你在兩個容器上操作,所以沒有任何STL魔法可以隱藏這個事實。

正如路易斯所說,這將適用於任何STL mapset容器。

+1

好吧,我想沒有什麼比在地圖上迭代更好。我不認識你使用的語法。 '(auto kv:map)'表示什麼?我本來只希望迭代(即循環)遍歷地圖的元素。 –

+1

@FaheemMitha這是新的C++ 11 for循環。它看起來確實如此,並且與「auto」結合使得事情變得更加整潔。 'auto'不需要明確寫出kv的類型。有幾種方法可以完成基本相同的事情,包括遍歷迭代器的for循環,帶有lambda的'for_each'等。由於您提到'unordered_map',我假設您使用的是C++ 11。 –

+0

我想我是,但我並沒有真正熟悉新標準。謝謝。 –

2

在STL中沒有內置方法從地圖獲取所有鍵或值。

迭代無序映射或常規映射沒有什麼不同,最好的方法是迭代它並將鍵或值收集到向量中。

您可以編寫一個模板函數來迭代任何種類的地圖。

6

使用C++ - 14你也可以做到以下幾點(編輯包含完整的源代碼):

#include <algorithm> 
#include <iostream> 
#include <string> 
#include <unordered_map> 
#include <vector> 

using namespace std; 

typedef string Key; 
typedef int Value; 

auto key_selector = [](auto pair){return pair.first;}; 
auto value_selector = [](auto pair){return pair.second;}; 

int main(int argc, char** argv) { 
    // Create a test map 
    unordered_map<Key, Value> map; 
    map["Eight"] = 8; 
    map["Ten"] = 10; 
    map["Eleven"] = 11; 

    // Vectors to hold keys and values 
    vector<Key> keys(map.size()); 
    vector<Value> values(map.size()); 

    // This is the crucial bit: Transform map to list of keys (or values) 
    transform(map.begin(), map.end(), keys.begin(), key_selector); 
    transform(map.begin(), map.end(), values.begin(), value_selector); 

    // Make sure this worked: Print out vectors 
    for (Key key : keys) cout << "Key: " << key << endl; 
    for (Value value : values) cout << "Value: " << value << endl; 

    return 0; 
} 

我編這個用下面的命令:

g++ keyval.cpp -std=c++14 -o keyval 

測試它打印鍵和值如預期。

+0

你能解釋一下嗎 – Whitecat

+0

你能寫一個可以編譯的獨立的例子嗎?另外,如果您可以提及要使用的編譯器並提供一個命令行來編譯它,那將會很有幫助。謝謝。 –

+0

另外,這裏是什麼'Key'和'Value'和'um'?你還沒有定義它們。也許你正在使用這個問題的定義,即「unordered_map um;」,但在這種情況下,無論如何,你都應該再次提到這一點。 –

0

加入很晚,但認爲這可能對某人有幫助。
使用key_typemapped_type的兩個模板函數。

namespace mapExt 
{ 
    template<typename myMap> 
    std::vector<typename myMap::key_type> Keys(const myMap& m) 
    { 
     std::vector<typename myMap::key_type> r; 
     r.reserve(m.size()); 
     for (const auto&kvp : m) 
     { 
      r.push_back(kvp.first); 
     } 
     return r; 
    } 

    template<typename myMap> 
    std::vector<typename myMap::mapped_type> Values(const myMap& m) 
    { 
     std::vector<typename myMap::mapped_type> r; 
     r.reserve(m.size()); 
     for (const auto&kvp : m) 
     { 
      r.push_back(kvp.second); 
     } 
     return r; 
    } 
} 

用法:

std::map<long, char> mO; 
std::unordered_map<long, char> mU; 
// set up the maps 
std::vector<long> kO = mapExt::Keys(mO); 
std::vector<long> kU = mapExt::Keys(mU); 
std::vector<char> vO = mapExt::Values(mO); 
std::vector<char> vU = mapExt::Values(mU);