
Originally Posted by
doberkofler
Unfortunately I need to order of insertion and this would not seem to work with QMap.
You can't have both at once without duplicating information. Hash-based access requires items to be ordered (somehow) according to the hash, otherwise using the hash has no benefit. Long story short - you need two structures, as already suggested.
But I would do it the other way round - keep the "main" data in the list and have a hash for mapping item id to position in the sequence. It somehow seems more appropriate to me than storing data in the hash and then the pointers to those items in the list.
template <class T> class HashedList : public QVector<T> {
public:
//...
void addItem(const T &item) {
int h = qHash(item);
int pos = count();
m_hash.insert(h, pos);
append(item);
}
int hashedIndexOf(const T& item) const {
int h = qHash(item);
return m_hash.value(h, -1);
}
// etc.
private:
QHash<int, int> m_hash;
};
template <class T> class HashedList : public QVector<T> {
public:
//...
void addItem(const T &item) {
int h = qHash(item);
int pos = count();
m_hash.insert(h, pos);
append(item);
}
int hashedIndexOf(const T& item) const {
int h = qHash(item);
return m_hash.value(h, -1);
}
// etc.
private:
QHash<int, int> m_hash;
};
To copy to clipboard, switch view to plain text mode
Note that this REQUIRES hashes to be unique. If you can't guarantee that, substitute the integer with the item "name" (QString). Alternatively make your class implicitly or better yet explicitly shared and have two separate structures with shallow copies of the items. With implicit sharing this gets tricky, explicit sharing is best. An alternative is to use pointers as JohannesMunk suggested.
Bookmarks