Подскажите, пожалуйста, есть ли какой нибудь контейнер поддерживающий составной ключ с динамической длинной?
Задача:
Есть структура с полями. И для нее идеально подошёл boost::multy_index_container. Можно индексировать и сортировать данные по любому полю структуры.
Но пришлось поменять одно поле в структуре на vector идентификаторов. И хотелось бы быстро находить все структуры в которых ключ содержит требуемый идентификатор. Но ничего не приходит в голову кроме полного перебора. Длина вектора очень произвольная.
Заранее спасибо!
Здравствуйте, Sergey_BG, Вы писали:
S_B>Подскажите, пожалуйста, есть ли какой нибудь контейнер поддерживающий составной ключ с динамической длинной?
S_B>Задача:
S_B>Есть структура с полями. И для нее идеально подошёл boost::multy_index_container. Можно индексировать и сортировать данные по любому полю структуры.
S_B>Но пришлось поменять одно поле в структуре на vector идентификаторов. И хотелось бы быстро находить все структуры в которых ключ содержит требуемый идентификатор. Но ничего не приходит в голову кроме полного перебора. Длина вектора очень произвольная.
S_B>Заранее спасибо!
Boost Multi-index может только ассоциации типа one-one (уникальные индексы) и оne-many (не уникальные), в твоем же случае имеет место many-many, поэтому Boost Multi-index пролетает. Придется мутить что то кастомное, структурно типа такого
struct MyElement
{
std::vector<Identifier> identifiers;
};
struct MyIndex
{
std::map<Identifier, std::set<MyElement*>> id2els;
void add(MyElement* e)
{
for(Identifier id : e->identifiers)
id2els[id].insert(e);
}
void del(MyElement* e)
{
for(Identifier id : e->identifiers)
{
auto iter = id2els.find(id);
assert(id2elements.end() != iter);
std::set<MyElement*>& els = iter->second;
assert(els.contains(e));
els.remove(e);
if(els.empty())
id2els.erase(iter);
}
//или, если не волнует мусорная пустота, можно вместо этого огорода сделать попроще
//for(Identifier id : e->identifiers)
// id2elements[id].remove(e);
}
const std::set<MyElement*>& find(Identifier id) const
{
if(auto iter = id2els.find(id); id2els.end() != iter)
return iter->secind;
static const std::set<MyElement*> emptyResult;
return emptyResult;
}
};