我对字典有意见,希望你能帮我。
我有以下声明:
class MainCollection<TKey1, TKey2, TValue> : Dictionary<KeyValuePair<TKey1, TKey2>, TValue>问题是,我无法从本词典中获得一个由TKey1 或 TKey2提供的元素。是否只有TKey1或TKey2才能获得元素,而不是TKey1和TKey2?
我编写了以下代码:
public TValue GetItemByKey1(TKey1 key)
{
MainCollection<int, int, string> Coll = new MainCollection<int, int, string>();
var value = from s in Coll where s.Key.Key == key select s.Value;
}但它已经有两个问题:
我怎样才能解决这些错误?我在这里没有发现任何相关的问题。提前感谢!
发布于 2011-09-01 14:42:36
好的,所以您希望能够通过TKey1或TKey2进行查找。然后你想要的是三本字典,每个键一本,然后一本钥匙对。
class Foo<TFirstKey, TSecondKey, TValue> {
private readonly Dictionary<TFirstKey, List<TValue>> firstDictionary
= new Dictionary<TFirstKey, List<TValue>>();
private readonly Dictionary<TSecondKey, List<TValue>> secondDictionary
= new Dictionary<TSecondKey, List<TValue>>();
private Dictionary<Tuple<TFirstKey, TSecondKey>, TValue> dictionary
= new Dictionary<Tuple<TFirstKey, TSecondKey>, TValue>();
public IEnumerable<TValue> GetByFirstKey(TFirstKey firstKey) {
return this.firstDictionary[firstKey];
}
public IEnumerable<TValue> GetBySecondKey(TSecondKey secondKey) {
return this.secondDictionary[secondKey];
}
public TValue GetByKey(TFirstKey firstKey, TSecondKey secondKey) {
return this.dictionary[Tuple.Create(firstKey, secondKey)];
}
public void Add(TFirstKey firstKey, TSecondKey secondKey, TValue value) {
this.dictionary.Add(Tuple.Create(firstKey, secondKey), value);
if(this.firstDictionary.Keys.Contains(firstKey)) {
this.firstDictionary[firstKey].Add(value);
}
else {
this.firstDictionary.Add(firstKey, new List<TValue> { value });
}
if(this.secondDictionary.Keys.Contains(secondKey)) {
this.secondDictionary[secondKey].Add(value);
}
else {
this.secondDictionary.Add(secondKey, new List<TValue> { value });
}
}
}请注意,只有(TFirstKey, TSecondKey)查找是唯一的,因此需要GetByFirstKey和GetBySecondKey返回集合。
剩下的细节交给你。
关键是,如果您希望快速查找任何一个键,您需要两个字典(一个为每个坐标的密钥对)。使用一个键可以通过查询键集来工作,但这很慢(搜索键是线性的)。
发布于 2011-09-01 14:42:07
只需将一个方法添加到集合本身:
public TValue GetItemByKey1(TKey1 key)
{
var value = from s in this.Keys where s.Key.Key == key select this[s];
return value.SingleOrDefault();
}对于TKey2,您可以有类似的方法。
请注意,这些查找将比标准字典键查找慢得多,因为您正在迭代密钥集合,而不是利用字典本来会使用的哈希表。
发布于 2011-09-01 15:16:22
我建议不要使用KeyValuePair<TKey, TValue>,因为KVP是一个结构,并且作为字典中的一个键表示对象将存在一段时间。我会推荐一个Tuple<T1, T2>代替。它的好处是元组是一种参考类型,您可以自由地传递而不复制。而且,Tuple是一个只读对象,就像KVPair一样。以下是我写它的方式:
class Program
{
static void Main(string[] args)
{
MainCollection<int, string, DateTime> collection = new MainCollection<int, string, DateTime>();
collection.Add(Tuple<int, string>.Create(1, "Bob"), new DateTime(1992, 12, 1));
collection.Add(Tuple<int, string>.Create(2, "James"), new DateTime(1945, 9, 1));
collection.Add(Tuple<int, string>.Create(3, "Julie"), new DateTime(1976, 7, 15));
DateTime date;
date = collection.GetValue(1);
Console.WriteLine("Bob birthdate: {0}", date);
date = collection.GetValue("Julie");
Console.WriteLine("#3 birthdate: {0}", date);
Console.ReadLine();
}
}
public class MainCollection<TKey1, TKey2, TValue>
{
Tuple<TKey1, TKey2> key;
Dictionary<Tuple<TKey1, TKey2>, TValue> mainCollection = new Dictionary<Tuple<TKey1, TKey2>, TValue>();
public void Add(Tuple<TKey1, TKey2> Key, TValue Value)
{
mainCollection.Add(Key, Value);
}
public TValue GetValue(TKey1 Key)
{
return mainCollection.Where(k => k.Key.Item1.Equals(Key))
.Select(v => v.Value)
.FirstOrDefault();
}
public TValue GetValue(TKey2 Key)
{
return mainCollection.Where(k => k.Key.Item2.Equals(Key))
.Select(v => v.Value)
.FirstOrDefault();
}
}
public class Tuple<T1, T2>
{
readonly T1 item1;
readonly T2 item2;
Tuple(T1 item1, T2 item2)
{
this.item1 = item1;
this.item2 = item2;
}
public static Tuple<T1, T2> Create(T1 Item1, T2 Item2)
{
return new Tuple<T1, T2>(Item1, Item2);
}
public T1 Item1
{ get { return item1; } }
public T2 Item2
{ get { return item2; } }
}
}注意:我包含了一个元组实现,以防您不使用.Net 4.0
更新
将MainCollection对象转换为使用多个字典如下所示:
public class MainCollection<TKey1, TKey2, TValue>
{
Tuple<TKey1, TKey2> key;
Dictionary<TKey1, Tuple<TKey1, TKey2>> k1Dictionary = new Dictionary<TKey1, Tuple<TKey1, TKey2>>();
Dictionary<TKey2, Tuple<TKey1, TKey2>> k2Dictionary = new Dictionary<TKey2, Tuple<TKey1, TKey2>>();
Dictionary<Tuple<TKey1, TKey2>, TValue> mainCollection = new Dictionary<Tuple<TKey1, TKey2>, TValue>();
public void Add(Tuple<TKey1, TKey2> Key, TValue Value)
{
mainCollection.Add(Key, Value);
k1Dictionary.Add(Key.Item1, Key);
k2Dictionary.Add(Key.Item2, Key);
}
public TValue GetValue(TKey1 Key)
{
return mainCollection[k1Dictionary[Key]];
}
public TValue GetValue(TKey2 Key)
{
return mainCollection[k2Dictionary[Key]];
}
}https://stackoverflow.com/questions/7271927
复制相似问题