什么是多维数组的集合?

时间:2009-07-23 02:43:21

标签: c# collections

我有一组看起来像这样的数据:

001 001 One
001 002 Two
001 003 Three

002 001 One
002 002 Two
002 003 Three

...

现在,当然,我可以创建一个字符串[x] [y] = z的数组,但是这个数组必须是可调整大小的,我更喜欢使用索引器的字符串表示而不是转换为数字。原因是我需要按字符串查找数据,而且我没有看到不必要的字符串 - >数字转换的重点。

我的第一个想法是:

Dictionary<string, Dictionary<string, string>> data;

data = new Dictionary<string, Dictionary<string, string>>();

Dictionary<string, string> subdata = Dictionary<string, string>();

subdata.Add(key, string);
data.add(key2, subdata);

这有效,但有点麻烦。它也感觉不对劲,而且不是特别有效。

那么在集合中存储此类数据的最佳方法是什么?

我还想过创建自己的集合类,但如果不需要,我宁愿不这样做。我宁愿只使用现有的工具。

6 个答案:

答案 0 :(得分:5)

这是非常常见的请求,大多数人最终会编写一些Tuple类的变体。如果您使用的是ASP.Net,则可以使用已经可用的Triple类,否则请编写如下内容:

public class Tuple<T, T2, T3>
{
    public Tuple(T first, T2 second, T3 third)

    {
        First = first;
        Second = second;
        Third = third;
    }

    public T First { get; set; }
    public T2 Second { get; set; }
    public T3 Third { get; set; }

}

有一个通用的三元组类,因此您可以创建一个新的List<Tuple<string, string, string>>()并创建您的元组并添加它们。使用一些索引功能扩展该基本类,然后就可以了。

编辑:带有字典的列表似乎不是正确的方法,因为每个字典只保存一个值。键和值之间没有多项关系 - 只有一个多部分键和一个关联值。数据等同于数据库行(或元组!)。

Edit2:这是一个可以为方便起见而使用的可索引列表类。

    public class MyTupleList : List<Tuple<string, string, string>>
    {
        public Tuple<string, string, string> this[string first, string second]
        {
            get
            {
                return (this.Find(x => x.First == first && x.Second == second));
            }
            set
            {
                this[first, second] = value;
            }
        }
    }

答案 1 :(得分:4)

我认为这实际上取决于你在这里建模的内容。如果您计划使用面向对象的方法,则不应将这些视为数据结构中的任意项。

我猜这看起来前两列是其他项目的“关键”。定义一个简单的结构,并创建一个类似的字典:

struct Key {
   public int Val1 { get; set; }
   public int Val2 { get; set; }
}

....

Dictionary<Key, string> values;

显然Key和它内部的项目应该映射到更接近你所代表的东西。

答案 2 :(得分:3)

如果有合适的Pair<A,B>类*,left as an exercise for the reader,您可以使用Dictionary<Pair<string, string>, string>

*具有相等性和哈希码的类会覆盖,没有什么特别难的。

答案 3 :(得分:1)

List<List<T>>会为你效力吗?仍然是kludgy,但比字典恕我直言。


编辑:如果Dictionary<string,string>并将两个键映射到单个字符串呢?

var data = new Dictionary<string,string>(StringComparer.Ordinal);

data[GetKey("002", "001")] = "One";

string GetKey(string a, string b) {
    return a + "\0" + b;
}

答案 4 :(得分:1)

在这种情况下,

List<List<string>>确实是你最好的选择。但我同意,这是愚蠢的。就个人而言,我会创建一个实现二维索引器的自定义类,并可能在内部使用List<List<T>>

例如:

public class DynamicTwoDimensonalArray<T>
{
  private List<List<T>> Items = new List<List<T>>();

  public T this[int i1, int i2]
  {
    get
    {
      return Items[i1][i2];
    }
    set
    {
      Items[i1][i2] = value;
    }
  }  
}

这是让你前进的基本想法;显然,setter需要处理边界问题。但这是一个开始。

修改:

  

号。正如我所说,我宁愿用字符串索引它们。并且它们可能并不总是顺序的(中间可能缺少数字)。 - Mystere Man

嗯......这很有意思。如果是这种情况,最好的办法是创建两种索引器组合的某种连接,并将其用作单级字典中的键。我仍然会使用自定义类来更轻松地使用索引。例如:

public class TwoDimensionalDictionary
{
  private Dictionary<string, string> Items = new Dictionary<string, string>();

  public string this[string i1, string i2]
  {
    get
    {
      // insert null checks here
      return Items[BuildKey(i1, i2)];
    }
    set
    {
      Items[BuildKey(i1, i2)] = value;
    }
  }
  public string BuildKey(string i1, string i2)
  {
    return "I1: " + i1 + " I2: " + i2;
  }  
}

答案 5 :(得分:0)

如果您需要按给定的z找到(x,y)(例如,根据给定的y找不到所有x),请使用此:

Dictionary<KeyValuePair<string, string>, string>

否则,你的字典就好了。