четверг, 25 февраля 2010 г.

DirectMap - упорядоченный map

Недостаток ассоциативного массива QMap в том, что в нем ключи упорядочиваются. Т.е. если я добавлю в QMap" Key2", "Key1", то на выходе получу, сюрприз, "Key1", "Key2". Ключи будут отсортированы.
Такое поведение честно говоря подзае..ло, а альтернативы в Qt нету.
В качестве альтернативы они предлагают использовать QList<QPair<>>. Крайне громоздкая структура.
Наконец я решил сделать класс с удобством пользования как у QMap и с функционалом как у QList, т.е. без автоматического упорядочивания по ключам.

Начнем пожалуй.

#ifndef DIRECTMAP_H
#define DIRECTMAP_H

#include <QList>
#include <QPair>

//---------------------------------------------------------------------
template <class Key, class Value>
class DirectMap : private QList<QPair<Key, Value> >
{
public:
  //! Добавляем пару
  void append(const Key &, const Value &);
  //! Список ключей
  QList<Key> keys() const;
  //!
  Value operator[](const Key & key) const;
};

//---------------------------------------------------------------------
template <class Key, class Value>
void DirectMap<Key, Value>::append(const Key & key, const Value & value)
{
  QList::append(qMakePair(key, value));
}
//---------------------------------------------------------------------
template <class Key, class Value>
QList<Key> DirectMap<Key, Value>::keys() const
{
  QList<Key> resKeys;
  for (int i = 0; i < QList::count(); ++i)
  {
   resKeys.append(QList::at(i).first);
  }
  return resKeys;
}
//---------------------------------------------------------------------
template <class Key, class Value>
Value DirectMap<Key, Value>::operator[](const Key & key) const
{
  for (int i = 0; i < QList::count(); ++i)
  {
   if (QList::at(i).first == key)
   {
     return QList::value(i).second;
   }
  }
  return Value();
}
//---------------------------------------------------------------------

#endif


* This source code was highlighted with Source Code Highlighter.

Пример использования:
  DirectMap<QString, QString> dmap;
  dmap.append("key3", "value3");
  dmap.append("key2", "value2");
  dmap.append("key1", "value1");
 
  DirectMap<QString, int> dmap1;
  dmap1.append("key3", 3);
  dmap1.append("key2", 2);
  dmap1.append("key1", 1);

  foreach(QString key, dmap.keys())
  {
   qDebug() << key << dmap[key];
  }
  foreach(QString key, dmap1.keys())
  {
   qDebug() << key << dmap1[key];
  }

* This source code was highlighted with Source Code Highlighter.

Как видим - удобство QMap, но без автосортировки. Удобно.

3 комментария:

  1. "а альтернативы в Qt нету"

    А QHash не подойдеть?

    QHash provides very similar functionality to QMap. The differences are:

    -QHash provides faster lookups than QMap. (See Algorithmic Complexity for details.)

    -When iterating over a QMap, the items are always sorted by key. With QHash, the items are arbitrarily ordered.

    =Зямбер=

    ОтветитьУдалить
    Ответы
    1. Омг... QHash вообще раскидывает в случайном порядке, о чем вы? Автору спасибо за пример!

      Удалить
  2. Вона што. Мда, собственно, я мог бы и сам догадаться, что стандартные коллекции ты в первую очередь просмотришь в поисках альтернативы )))

    ОтветитьУдалить