2012-03-29 4 views
0

私はstd::deque<record *>に格納されたテーブル全体を持っており、ユーザが任意のカラムでテーブルをソートできるようにする必要があります。表は、リストボックス形式でユーザーに提示されます。複数のデータ型で動作するようにstd :: mapを比較するには?

各レコードは複数の文字列(文字列の構造体)で構成されています。ただし、フィールドはすべて文字列として格納されていますが、時間(HH:MM:SS)、浮動小数点数、および文字列の型が異なります。

ユーザーは、これらの列のいずれかで並べ替えることができます。ユーザーが列をクリックすると、テーブルがソートされた形式でユーザーに表示されるように、各レコードがマルチマップに格納されます。

しかし、列の種類が異なるため、これらをすべて効率的に処理する1つの比較方法を作成するにはどうすればよいですか。

私はタイプごとに、次の方法

  1. 使用異なるマップを考え、もう1つはマップごとに機能のクラスを比較する書き込み。
  2. 3つの異なるすべての型を処理する比較クラスを使用して、単一のマップを使用します。しかし、挿入するたびに、比較クラスは型を決定し、それに応じて挿入する必要があります。

この2つの方法よりも良い方法はありますか?

例:

struct ltDataCompare 
{ 

    bool operator()(const CString& csData1, const CString& csData2) const 
    { 

     if (isTimeFormat(csData1) && isTimeFormat(csData1)) 
     { 
       // Do time relevant comparision 
      } 
      else if (isNumberFormat(csTime1) && isNumberFormat(csTime2)) 
     { 
      double dPrice1 = atof((LPCTSTR)csTime1); 
      double dPrice2 = atof((LPCTSTR)csTime2); 

      return (dPrice1 < dPrice2); 
     } 
     return (csTime1 < csTime2); 
    } 
}; 

std::multimap<CString,list_record_t*,ltDataCompare> _mapAllRecords; // Used only for sorting 
+0

あなたは何を比較していますか?浮動小数点数を文字列と比較するのは意味がありますか?編集:申し訳ありませんが、私はあなたが意味するものを参照してください。レコードの1つまたは複数のフィールドをソートする必要があります。さて、ソート関数(またはラムダ)に渡すフィールドenumでこれを行うことができます。その後、enum値に応じて比較関数で適切な値を使用します。 – Robinson

+0

Robinsonの例を示してください。 – user373215

+0

Robinsonでは、すべてのフィールドが文字列として格納されます。私はフィールドの種類を決定し、適切な並べ替え/比較を行う必要があります。 – user373215

答えて

1

あなたはmapまたはmultimap再ソートすることはできません - 項目が挿入されると、その位置がロックされています。 vectorのような別のコンテナを使用し、必要に応じてソートする方がよいでしょう。

比較クラスの素晴らしい点は、状態を含むことが許可されていることです。使用する比較メソッドを決定するために、定数またはポインタを持つメンバを持つことができます。

同じ原則を使用して、並べ替えるフィールドを選択できます。

struct ltDataCompare 
{ 
    ltDataCompare(int field, int method) : m_field(field), m_method(method) {} 
    bool operator()(const record& left, const record& right) const 
    { 
     if (m_method == enumTimeFormat) 
      return CompareTimes(left[m_field], right[m_field]); 
     else if (m_method == enumNumberFormat) 
      return CompareNumbers(left[m_field], right[m_field]); 
     // ... 
    } 
    int m_field; 
    int m_method; 
}; 

std::sort(table.begin(), table.end(), ltDataCompare(0, enumTimeFormat)); 
+0

マーク、私はマップが解決できないことを理解しています。私はマップ/マルチマップを使用して、レコードを順番に保つだけです。これらがソートされると、map/multimapは必要ありません。私はそれらを破壊することができます。あなたは例/リンクを表示できますか? – user373215

+0

「同じ原則を使って並べ替えるフィールドを選択する」の例/リンクを表示できますか? – user373215

+0

@ user373215:ソートにのみ使用している場合は、通常のコンテナ(例えば 'std :: vector <>'や 'std :: deque <>')+ 'std :: sort'を使用して、全部。 – ildjarn

0

あなたはそれについての詳細エレガント可能性 - 私はあなたが自分ですべての作業を保存したいかわからない - あなたは種類ごとに、その中に<演算子を持つクラスを持っていた場合。あなたは仮想<演算子を持つスーパークラスを持っているなら、あなたは今、あなたはあまりにも長い間、あなたが一貫しているとして(実際のキーとして子タイプのいずれかを使用することができます

std::multimap< superclass, list_record_t > 

のように、キータイプとして使用することができます)。 実際に私はこれがもっと巧妙かよりエレガントかどうかは分かりません。もっと賢いのは一般的に悪いことです(それはより曖昧な/保守の難しいことを意味する)。コードの行数を減らすと、それは通常は良いことです。

関連する問題