2016-10-06 59 views
0

鑑於東西的集合,被建模爲:集裝箱訂貨要求(在努力瞭解的boost :: multi_index)

struct Foo { int id; std::string name; }; 

其中id是獨一無二的,name是非唯一/非{NULL |空}。

如何使用類似的boost :: multi_index一個數據結構,這將讓我做等價的:

select id, name from Foo group by name order by id 

標準STL容器沒有得到我應許之地。我使用了上面的一個sql變體來解釋我的觀點。我沒有真正處理任何數據庫。

UPDATE:

所以,顯然我需要的是:

typedef boost::multi_index_container< 
    Foo, 
    indexed_by< 
    ordered_unique<identity<Foo>>, 
    ordered_unique<member<Foo, std::string, &Foo::name>> 
    > 
> MIC; 

有人可以證實我有這個權利?它似乎工作。我還沒有測試過。

+0

可能重複[std :: map,如何按值排序,然後按鍵](http://stackoverflow.com/questions/19842035/stdmap-how-to-sort-by-value-then-by -key) – Treycos

+0

@Treycos它根本不重複。請再看看我的sql查詢。我沒有要求按ID排序,然後按名稱排序。我說我想按ID排序,同時將所有*相同的*名稱分組,並將它們分配給它們中的任何一個。所以{1,「Foo」} {2,「Bar」} {3,「Foo」}最終會返回{1,「Foo」} {2,「Bar」} **或** {2,「Bar」 } {3,「Foo」} – ForeverLearning

+0

能有人比我更有效嗎?刪除那個「這個問題可能已經有了答案」的標籤?我的情況看起來不合適。 – ForeverLearning

回答

0

就使用boost而言,我並沒有太多使用它,但我不認爲這是必要的,這取決於您需要這種操作的效率。

如果您有一個標準庫容器Foo,爲了簡單起見,我們假設爲std::vector<Foo>。你可以做類似如下:

std::string nameToSearchFor("Bar"); 
std::vector<Foo> vecFoos; 
std::vector<Foo> results; 
auto it = std::find_if(it, vecFoos.cend(), [&](const Foo& foo) { 
    return (foo.name == nameToSearchFor); 
}); 

while (it != vecFoos.cend()) 
{ 
    results.emplace_back(*it); 

    it = std::find_if(it, vecFoos.cend(), [&](const Foo& foo) { 
     return (foo.name == nameToSearchFor); 
    }); 
} 

std::sort(results.begin(), results.end(), [](const Foo& lhs, const Foo& rhs) { 
    return lhs.id < rhs.id; 
}); 

這將與任何STL容器,或至少提供給它的元素ForwardIterator訪問任何容器中工作。但是,如果您使用的是類似std::unordered_multimap的內容,則需要利用其內部的find/equal_range方法。

有很多方法可以加快速度,但這是一種天真,快速且易於理解的方法,可以給你想要的東西,並且適用於小數據集。

+0

謝謝!我知道如何做到這一點很難。 boost :: multi_index似乎是爲此量身定製的,我想看看如何免費獲得這些東西。我拍了一下,如果你看到我更新的帖子,它似乎工作。我還沒有用更多的投入進行廣泛的測試。 – ForeverLearning