如何编写导致字典的LINQ查询?

Iva*_*van 41 .net c# linq collections dictionary


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
Run Code Online (Sandbox Code Playgroud)

如何获取Dictionary <string,string>?

Nei*_*ght 42

您需要指定值 Dictionary

var d2 = q.ToDictionary(p => p.NickName, p => p.Name);
Run Code Online (Sandbox Code Playgroud)


Tim*_*ter 12

字典不能包含多个相等的键,因此您应该确保(或知道)不是这种情况.您可以使用GroupBy它来确保它:

Dictionary<string, string> dict = pl
        .Where(p => p.Name.First() == 'A')
        .GroupBy(p => p.NickName)
        .ToDictionary(g => g.Key, g => g.First().Name); 
Run Code Online (Sandbox Code Playgroud)


Jod*_*ell 8

编辑

如果你真的觉得你需要从获得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);
}
Run Code Online (Sandbox Code Playgroud)

然后你可以打电话ToDictionary()给任何人IEnumerable<KeyValuePair<TKey, TValue>>.

编辑2

如果您预计重复,那么您也可以创建一个ToLookup()扩展.

public static ILookup<TKey, TValue> ToLookup<TKey, TValue>(
    this IEnumerable<KeyValuePair<TKey, TValue>> source)
{
    return source.ToLookup(p => p.Key, p => p.Value);
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您确实要丢弃结果,则可以添加重载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));
}
Run Code Online (Sandbox Code Playgroud)

如果你随意丢弃除了"第一个"之外的所有内容(这意味着什么意思没有OrderBy),你可以像这样使用这个扩展,

pairs.ToDictionary(v => v.First()); 
Run Code Online (Sandbox Code Playgroud)

总的来说,您可以删除大部分代码并执行此操作,

var q = from p in pl
        where p.Name.First() == 'A';
var d = q.ToDictionary(p => p.NickName, p => p.Name);
Run Code Online (Sandbox Code Playgroud)

如果可能有重复,那么

var d = q.ToLookup(p => p.NickName, p => p.Name);
Run Code Online (Sandbox Code Playgroud)

但要注意,这个返回ILookup<TKey, TElement>时,Item它的索引,返回一个IEnumerable<TElement>这样你就不会丢弃数据.


Til*_*lak 5

尝试将NickName作为Key,并将Name命名为Value

var d2 = q.ToDictionary (p => p.NickName, p=>p.Name);
Run Code Online (Sandbox Code Playgroud)

但请注意,字典不允许重复,因此上面将为具有相同昵称的重复记录引发错误.也许你想使用类似于Dictionary的Lookup,但允许重复

var d2 = q.ToLookup (p => p.NickName, p=>p.Name);
Run Code Online (Sandbox Code Playgroud)