C++ (Qt)typedef QPair<QString, int> TKey; // имя + типtypedef QPair<QString, QPair<int, bool> > TKey; // имя + тип + видимочть
#include <QHash>#include <QVector>#include <QSet>#include <QDebug>#include <algorithm>struct ObjectInfo{ QString name; int type; bool visible;};QList<ObjectInfo> objects;QHash<QString, QList<int>> nameIndex;QHash<int, QList<int>> typeIndex;QHash<bool, QList<int>> visibleIndex;void fill(){ for (int i = 0; i < 100; ++i) { const QString name = QString("name%1").arg(qrand()%5); const int type = qrand()%27; const bool visible = (i%2); ObjectInfo objectInfo{name, type, visible}; const int index = objects.size(); nameIndex[name] << index; typeIndex[type] << index; visibleIndex[visible] << index; objects << objectInfo; }}int find(const QString& name, const int type, const bool visible){ auto it = nameIndex.find(name); if (it == nameIndex.cend()) // имя не найдено - увы return -1; if (it.value().isEmpty()) // ничего не проиндексировано - увы return -1; QSet<int> types = typeIndex.value(type).toSet(); QSet<int> visibles = visibleIndex.value(visible).toSet(); QSet<int> intersects = types.intersect(visibles); // пересекающиеся индексы типа и видимости if (intersects.isEmpty()) // ничего не персекается - возвращаем первый индекс по имени return it.value().first(); intersects = intersects.intersect(it.value().toSet()); //пересечение имени и типа/видимости if (intersects.isEmpty()) return it.value().first(); QList<int> indexes = intersects.toList(); auto min = std::min_element(indexes.cbegin(), indexes.cend()); return *min;}int main(int argc, char *argv[]){ Q_UNUSED(argc); Q_UNUSED(argv); fill(); const int index = find("name1", 5, true); if (index >= 0) qDebug() << objects.at(index).name; return 0;}