C# 多维数组的集合等价物是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1169317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:54:59  来源:igfitidea点击:

What is the collection equivalent of a multi-dimensional array?

c#collections

提问by Erik Funkenbusch

I've got a group of data that looks like this:

我有一组如下所示的数据:

001 001 One
001 002 Two
001 003 Three

002 001 One
002 002 Two
002 003 Three

...

Now, certainly, I could create an array of string[x][y] = z, but this array has to be resizable, and i'd prefer to use the string representations of the indexers than convert to numeric. The reason is that i will need to look up the data by string, and i don't see the point in needless string->number conversions.

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

My first thought was this:

我的第一个想法是这样的:

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);

and this works, but is somewhat cumbersome. It also feels wrong and kludgy and not particularly efficient.

这有效,但有点麻烦。它也感觉错误和笨拙,而且效率不高。

So what's the best way to store this sort of data in a collection?

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

I also thought of creating my own collection class, but I'd rather not if I don't have to. I'd rather just use the existing tools.

我也想过创建自己的收藏类,但如果没有必要,我宁愿不这样做。我宁愿只使用现有的工具。

采纳答案by womp

This is pretty common request, and most people end up writing some variation of a Tuple class. If you're using ASP.Net, you can utilize the Tripleclass that's already available, otherwise, write something like:

这是很常见的请求,大多数人最终都会编写一些元组类的变体。如果您使用的是 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; }

}

There's a generic three-tuple class, so you can create a new List<Tuple<string, string, string>>()and create your tuples and add them. Expand on that basic class with some indexing functionality and you're up up and away.

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

Edit: A list with a dictionary doesn't seem like the correct approach, because each dictionary is only holding one value. There is no multi-entry relationship between the key and values - there is simply one multi-part key and one associated value. The data is equivalent to a database row (or tuple!).

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

Edit2: Here's an indexable list class you could use for convenience.

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;
            }
        }
    }

回答by dtb

Would a List<List<T>>work for you? Still kludgy, but better than dictionaries IMHO.

List<List<T>>为你工作吗?仍然笨拙,但比字典更好恕我直言。



EDIT: What about a Dictionary<string,string>and mapping the two keys to a single string?

编辑: aDictionary<string,string>和将两个键映射到单个字符串怎么样?

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

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

with

string GetKey(string a, string b) {
    return a + "
struct Key {
   public int Val1 { get; set; }
   public int Val2 { get; set; }
}

....

Dictionary<Key, string> values;
" + b; }

回答by Ryan Brunner

I think this really depends on what you are modelling here. If you're planning to use an object-oriented approach, you shouldn't be thinking of these as arbitrary items inside a data structure.

我认为这真的取决于你在这里建模的内容。如果您打算使用面向对象的方法,则不应将它们视为数据结构中的任意项。

I'm guessing from looking at this that the first two columns are serving as a "key" for the other items. Define a simple struct, and create a dictionary of like so:

我从这个角度猜测前两列是其他项目的“关键”。定义一个简单的结构体,并像这样创建一个字典:

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;
    }
  }  
}

Obviously Key and the items inside it should be mapped to something closer to what you are representing.

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

回答by Randolpho

List<List<string>>is really your best bet in this case. But I agree, it's kludgy. Personally, I would create a custom class that implements a two-dimensional indexer and maybe use a List<List<T>>internally.

List<List<string>>在这种情况下真的是你最好的选择。但我同意,它很笨拙。就个人而言,我会创建一个实现二维索引器的自定义类,并且可能在List<List<T>>内部使用。

For example:

例如:

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;
  }  
}

This is a basic idea to get you going; clearly the setter needs to deal with bounds issues. But it's a start.

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

Edit:

编辑:

No. As I said, I would prefer to index them by string. And they may not always be sequential (might have a missing number in the middle).- Mystere Man

不。正如我所说,我更愿意按字符串索引它们。而且它们可能并不总是连续的(中间可能缺少数字)。-神秘人

Hmm... this is interesting. If that's the case, your best bet would be to create some sort of concatenation of the combination of the two indexers and use that as the key in a single-level dictionary. I would still use a custom class to make using the indexing easier. For example:

嗯……这很有趣。如果是这种情况,最好的办法是创建两种索引器组合的某种串联,并将其用作单级字典中的键。我仍然会使用自定义类来简化索引的使用。例如:

Dictionary<KeyValuePair<string, string>, string>

回答by John Kugelman

Given a suitable Pair<A,B>class*, left as an exercise for the reader, you could use a Dictionary<Pair<string, string>, string>.

给定一个合适的Pair<A,B>类*,作为练习留给读者,您可以使用Dictionary<Pair<string, string>, string>.

* A class with equality and hash code overrides, nothing terribly hard.

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

回答by Pavel Minaev

If you are ever going to need to find zby given (x,y)(and not, for example, find all yby given x), then use this:

如果您需要z通过 given查找(x,y)(而不是,例如,查找 all yby given x),请使用以下命令:

##代码##

Otherwise, your dictionary is fine as is.

否则,您的字典就可以了。