如何编写一个导致字典的LINQ查询?
public class Person { public string NickName{ get; set; } public string Name{ get; set; } } var pl = new List<Person>; var q = from p in pl where p.Name.First() == 'A' orderby p.NickName select new KeyValuePair<String, String>(p.NickName, p.Name); var d1 = q.ToList(); // Gives List<KeyValuePair<string, string>> var d2 = q.ToDictionary(); // Does not compile
如何获得词典<string,string>?
您需要指定Dictionary
的值
var d2 = q.ToDictionary(p => p.NickName, p => p.Name);
字典不能包含多个相等的密钥,所以你应该确保(或者知道)情况并非如此。 你可以使用GroupBy
来确保它:
Dictionary<string, string> dict = pl .Where(p => p.Name.First() == 'A') .GroupBy(p => p.NickName) .ToDictionary(g => g.Key, g => g.First().Name);
编辑
如果你真的觉得你需要隐式地从IEnumerable<KeyValuePair<TKey, TValue>>
到一个Dictionary
你可以添加这个扩展。
public static IDictionary<TKey, ToValue> ToDictionary<TKey, TValue>( this IEnumerable<KeyValuePair<TKey, TValue>> source) { return source.ToDictionary(p => p.Key, p => p.Value); }
然后,您可以在任何IEnumerable<KeyValuePair<TKey, TValue>>
上调用ToDictionary()
。
编辑2
如果您预计重复,那么您也可以创build一个ToLookup()
扩展。
public static ILookup<TKey, TValue> ToLookup<TKey, TValue>( this IEnumerable<KeyValuePair<TKey, TValue>> source) { return source.ToLookup(p => p.Key, p => p.Value); }
或者,如果您确实想放弃结果,则可以为ToDictionary
添加一个重载。
public static IDictionary<TKey, ToValue> ToDictionary<TKey, TValue>( this IEnumerable<KeyValuePair<TKey, TValue>> source, Func<<IEnumerable<TValue>, TValue> selector) { return source .Lookup(p => p.Key, p => p.Value); .ToDictionary(l => l.Key, l => selector(l)); }
如果你任意丢弃除“第一”(这是什么意思没有OrderBy
)项目的所有,你可以使用这样的扩展,
pairs.ToDictionary(v => v.First());
总的来说,你可以删除大部分的代码,
var q = from p in pl where p.Name.First() == 'A'; var d = q.ToDictionary(p => p.NickName, p => p.Name);
如果可能有重复, 请执行
var d = q.ToLookup(p => p.NickName, p => p.Name);
但是请注意,这将返回一个ILookup<TKey, TElement>
,它的Item
索引器将返回一个IEnumerable<TElement>
所以您不会丢弃数据。
尝试关注NickName作为关键字,并将其命名为Value
var d2 = q.ToDictionary (p => p.NickName, p=>p.Name);
但是请注意,字典不允许重复,所以上面的将重复logging相同的绰号的错误。 也许你想使用类似于字典的查找,但允许重复
var d2 = q.ToLookup (p => p.NickName, p=>p.Name);
我意识到这是用c#标记的,但是我实际上只是想知道如何在vb.net中做到这一点,所以我想我会分享你如何在VB中做到这一点:
Public Class Person Property NickName As String Property Name As String End Class Sub Main() Dim p1 As New List(Of Person) '*** Fill the list here *** Dim q = (From p In p1 Where p.Name.First = "A" Select p.NickName, p.Name).ToDictionary( Function(k) k.NickName, Function(v) v.Name) End Sub