我有一组看起来像这样的数据:
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);
这有效,但有点麻烦。它也感觉不对劲,而且不是特别有效。
那么在集合中存储此类数据的最佳方法是什么?
我还想过创建自己的集合类,但如果不需要,我宁愿不这样做。我宁愿只使用现有的工具。
答案 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>
否则,你的字典就好了。