2016-05-12 137 views
0

我有一個代表數據庫行的QMap。該項目是按列名索引:在QMap的特定偏移處獲取項目

QMap<QString, QVariant> mapOfItems_; 

然後我有通過columnn名稱檢索項目的方法:

QVariant ImportDataSourceRow::byName(const QString& name) 
{ 
    if(mapOfItems_.contains(name)) 
     return mapOfItems_.value(name); 
    else 
     throw NoSuchColumn(); 
} 

我想也實現方法,通過列索引獲取項目(0爲第一列):

如何從地圖中獲得偏移量爲index的值? QMap甚至保證按我的需要訂購?

+0

'return * std :: next(mapOfItems_.begin(),index);'? (請注意,它是線性的)。 – Jarod42

+0

地圖不適合按索引搜索。這就是爲什麼沒有相應的API。 – vahancho

回答

1

聯想(類似於字典的)容器,如QMapstd::map很少提供順序的索引來確定內部它們通常作爲樹狀數據結構來實現(例如,Red-Black Tree)。

值得注意的例外是boost的flat_map。它被實現爲一對連續的數組,其中鍵和值的映射用數組索引表示:映射鍵和值具有相同的索引。 flat_map由索引提供方法nth()訪問值:

boost::container::flat_map<std::string, float> geek_numbers; 
geek_numbers.emplace("pi", 3.14f); 
geek_numbers.emplace("e", 2.72f); 
geek_numbers.emplace(
    "Answer to the Ultimate Question of Life, The Universe, and " 
    "Everything", 
    42.0f); 
auto 0th = geek_numbers.nth(0); // 42.0f 
auto 1st = geek_numbers.nth(1); // 2.72f 
auto 2nd = geek_numbers.nth(2); // 3.14f 

flat_map「模擬」的std::map的接口和行爲,並通過排序關鍵要素。您可以使用自定義謂詞。

請注意,標準容器僅適用於最簡單的類數據庫使用案例。一般來說,數據庫是一個非常複雜的話題。有關於它的完整的theories。如果您的數據集很大並且需要執行復雜的索引和查詢,請考慮嵌入可用的數據庫引擎之一(例如SQLite或其他更多heavyweight ones)。

+0

在另一個答案中,@tomáš-zato說列名不是名字。所以這個信息在使用flat_map時會丟失,對吧? – Daniel82

1

QMap的條目保證按鍵排序,在你的情況下是QString :: operator <。

爲了讓地圖中的位置,你可以使用:

const auto it = mapOfItems.find(name); 
const auto index = std::distance(mapOfItems.begin(), it); 

注意,你的綽號(),如果你使用constFind(方法會更有效),並拋出如果返回的迭代器等於mapOfItems.constEnd (),而不是做兩個查找(包含和值())。

+0

我想我不能使用'QMap',因爲列順序不是名字。謝謝你的回答。你能推薦我應該使用什麼嗎?也許兩個數組 - 名稱和值? –

+0

如果你的項目列表不是太大,一個簡單快捷的方法就是QVector >對象,並且你可以使用at()和name來訪問你需要迭代的索引,但如果名單很小,那是可以接受的。 – Daniel82

+0

或者只是使用一個向量,其條目按列索引排序。但是,然後byName()將具有O(n)複雜性而不是O(log n)。 –

0

不推薦,但你可以嘗試這樣來做:

QList<QString> list = mapOfItems_.values(); 
if(index>=0 && index<list.count()) return list.at(index); 
return QString(); 

不知道它是怎麼用的QVariant工作雖然。