2009-06-08 21 views
2

基本的には以下のような文字列の行列であるデータ構造を構築したいと思います。C#の多次元データ構造

  1. 行の可変長いいえ
  2. Aは、固定列
  3. iは整数を取るメソッド呼び出しを介して、特定の行または列にあるものは何でもで取得できるようにする

のno行番号と引数としてのint col番号。さらに、行と列番号を使用する列の値を設定できるようにしたいと考えています。

私は...列リストが修正されます申し訳

EDITを、この自分自身を行うが、他の人がやるかもしれないものを見に開いています可能性があり、

+0

いいえ、いくつかのコンテキスト、たとえば(期待される)サイズ、行/列を追加できる頻度などを追加するために画像をペイントできますか? –

+0

列は修正されます。ユーザーが新しいレコードを追加して、行をかなり頻繁に追加できるUIコンポーネントのバックエンドになります。 大量のデータを扱わない(レコード数が20未満) – AJM

+0

編集(固定列)は、それを有効にします。 DataTableはより良いでしょう。しかし、面白くない。 –

答えて

5

DataTableとデータセット(データテーブルの基本的コレクションは)あなたが探しているもののために正常に動作します。

あなたが設定したら、あなたはその後、(自分のデータにアクセスすることができ列と次の構文を介してデータのあなたの行)を追加しました:

datatable.rows(index)("ColumnName") 

または

datatable.rows(rowindex)(columnindex) 
3

:-(私のミスは、データのように私には聞こえ表は最も簡単なopionだろう。

2

どうDictionary<System.Drawing.Point, string>に何かを基づかでしょうか?あなたが書くことができるように。

stringGrid.Add(new Point(3,4), "Hello, World!"); 

、このような辞書を含むクラスを作成し、あなたが探しているものを手に入れる、ほとんど無料。何かのような(未テストの)

class StringGrid 
{ 
    Dictionary<System.Drawing.Point, string> grid; 

    public StringGrid 
    { 
     this.grid = new Dictionary<System.Drawing.Point, string>(); 
    } 

    public string Get(int x, int y) 
    { 
     string result = null; 
     grid.TryGetValue(new Point(x,y), out result); 
     return result; 
    } 

    public void Set(int x, int y, string content) 
    { 
     var pos = new Point(x,y); 
     if (grid.ContainsKey(pos)) 
     { 
      if (content == null) 
      { 
       // no content, so just clear the cell. 
       grid.remove(pos); 
      } 
      else 
      { 
       // add new content 
       grid[pos].Value = content; 
      } 
     } 
     else if (content != null) 
     { 
      // new non-null content 
      grid.add(pos, content); 
     } 
    } 
} 

EDIT:また、実際にフラッシュを取得する場合は、

  • IComparable

この方法を実装する独自の構造体でSystem.Drawing.Pointを置き換え、リストは内部的にシンプルforeachを作り、その後、列で、行が発注されるだろうSortedList<,>

  • で辞書を置き換えます最初の行のすべての値を反復し、2番目の行の値を反復するのに十分なループ。 `IEnumerable``または行のコレクションに変換することができます。

  • +0

    2つのこと:1)インデクサーを使用する:) 2)ポイントの辞書は行列を長方形に保たない。私は#2の事柄を前提としています。 –

    +0

    これは実際に親切です。そして、あなた自身のインデクサーを巻き込むのは簡単でしょう。しかし、長方形のもの...列や行が追加されても、整列された状態に保つことができると思いますが、それはちょっとした作業です。それがギザギザになるのが簡単ならば簡単です。 –

    +0

    多かれ少なかれ私の考えですが、私はむしろDrawing.Pointを使用しないでください。それは非常にcontectのです。しかし、技術的にはOKです。すぐに使用できます。 –

    3

    2つ以上のディメンションが必要な場合、またはより汎用的なソリューションが必要な場合は、より具体的な機能が必要な場合や簡単に必要な場合は、必要に応じてネストされ、カスタムタイプでラップされますメソッド呼び出し。ロジックを持つ行、次に列のリストとして

    +0

    キーやIDがある場合は、高速アクセスのためにSortedList >を使用することができます。 – Marcom

    2

    私が欲しかった/自分自身をロールバックする必要がある場合(たとえば、私が何DataTable/DataSetに対処する必要はありませんでした)、私はList<List<T>>(またはList<List<object>>)の周りに何かを書くと思いますリストを長方形に保つ。

    • AddRow()は、新しい外側リストエントリを追加します。
    • AddColumn()は、内側のリストのすべてのリストに新しい項目を追加します。
    • this[int row, int col]は、this._Data[row][col]にアクセスします。

    何かがそうです。

    名前付き列が必要な場合は、Dictionary<K, List<V>>に切り替えます(リストにその列の行データが含まれている場合)。

    2

    両方向に展開できるようにしたい場合は、DataTableを選択するのがベストではありません。インタフェースについては

    、あなたは、インデクサプロパティを使用することができます。

    class Foo 
    { 
        public string this[int x, int y] 
        { 
         get { return GetData(x,y); } 
        } 
    } 
    

    バックエンドストレージのための、最良のオプションは、すなわち空のセルの多くがあるでしょう、予想される使用上のビットを依存しています。

    struct Index { public readonly int X, Y; } 
    

    を定義して、Equals()およびGetHashCode()メンバーをオーバーライドすることができます。最近、SOに関するこれに関するいくつかの質問がありました。その後

    、あなたはまだ行と列の制限を管理する必要があり、多分空のセルの取得を傍受したいDictionary < Index, string>

    を使用しています。