在.NET 3.5发布之前,我使用
Dictionary<TKey, List<TValue>>
用于包含数据。但我刚刚发现.NET 3.5提供了新的集合类型,它是ILookup类,可以代表我原来的复杂数据类型。
我总是使用LINQ扩展方法(ToLookup方法)创建ILookup对象。但我不知道如何修改ILookup对象。
有可能吗?或者我需要使用union方法创建并再次调用ToLookup方法。
谢谢,
答案 0 :(得分:4)
你没有,这是不可改变的。您列出了两个合理的选择;要么使用子集的字典,要么继续创建新的查找。
答案 1 :(得分:4)
以下是可以操作的ILookup
实现的示例。它包裹着Dictionary
个List
个元素。它完全是通用的。我想不出更好的名字。 :)
public class LookupDictionary<TKey, TElement> : ILookup<TKey, TElement>
{
private Dictionary<TKey, List<TElement>> _dicLookup = new Dictionary<TKey, List<TElement>>();
public LookupDictionary()
{
}
public LookupDictionary(ILookup<TKey, TElement> a_lookup)
{
foreach (var grouping in a_lookup)
{
foreach (var element in grouping)
AddElement(grouping.Key, element);
}
}
public IEnumerable<TElement> AllElements
{
get
{
return (from key in _dicLookup.Keys
select _dicLookup[key])
.SelectMany(list => list);
}
}
public int Count
{
get
{
return AllElements.Count();
}
}
public IEnumerable<TElement> this[TKey a_key]
{
get
{
List<TElement> list;
if (_dicLookup.TryGetValue(a_key, out list))
return list;
return new TElement[0];
}
}
public bool Contains(TKey a_key)
{
return _dicLookup.ContainsKey(a_key);
}
public void Add(TKey a_key, TElement a_element)
{
AddElement(a_key, a_element);
}
public void RemoveKey(TKey a_key)
{
_dicLookup.Remove(a_key);
}
public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator()
{
return GetGroupings().GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return (GetGroupings() as System.Collections.IEnumerable).GetEnumerator();
}
private void AddElement(TKey a_key, TElement a_element)
{
List<TElement> list;
if (!_dicLookup.TryGetValue(a_key, out list))
{
list = new List<TElement>();
_dicLookup.Add(a_key, list);
}
list.Add(a_element);
}
private IEnumerable<IGrouping<TKey, TElement>> GetGroupings()
{
return from key in _dicLookup.Keys
select new LookupDictionaryGrouping<TKey, TElement>
{
Key = key,
Elements = _dicLookup[key]
} as IGrouping<TKey, TElement>;
}
}
public class LookupDictionaryGrouping<TKey, TElement> : IGrouping<TKey, TElement>
{
public TKey Key
{
get;
set;
}
public IEnumerable<TElement> Elements
{
get;
set;
}
public IEnumerator<TElement> GetEnumerator()
{
return Elements.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return (Elements as System.Collections.IEnumerable).GetEnumerator();
}
}
答案 2 :(得分:0)
正如mquander所提到的,查找是不可变的。但是,您可以使用其他值或已删除的值构建新查找。
// Add a new value
myLookup = myLookup
.SelectMany(l => l.Select(v => new {l.Key, Value = v}))
.Union(new[] {new {Key = myNewKey, Value = myNewValue}})
.ToLookup(a => a.Key, a => a.Value);
// Remove an old value
myLookup = myLookup
.SelectMany(l => l.Select(v => new {l.Key, Value = v}))
.Where(a => a.Value != myOldValue)
.ToLookup(a => a.Key, a => a.Value);