41

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

如何获取字典<字符串,字符串>?

4

6 回答 6

42

您需要为Dictionary

var d2 = q.ToDictionary(p => p.NickName, p => p.Name);
于 2012-12-19T09:52:49.567 回答
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); 
于 2012-12-19T09:57:43.090 回答
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);
}

然后你可以调用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);
}

或者,如果你真的想丢弃结果,你可以为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);

但请注意,这会返回 an ILookup<TKey, TElement>,其中的Item索引器会返回 an ,IEnumerable<TElement>因此您不会丢弃数据。

于 2012-12-19T09:57:35.737 回答
5

尝试将 NickName 作为键,将名称作为值

var d2 = q.ToDictionary (p => p.NickName, p=>p.Name);

但请注意,字典不允许重复,因此上面会为具有相同昵称的重复记录抛出错误。也许您想使用类似于 Dictionary 但允许重复的 Lookup

var d2 = q.ToLookup (p => p.NickName, p=>p.Name);
于 2012-12-19T09:54:24.023 回答
0

我意识到这是用标记的,但我昨天只是想弄清楚如何在中执行此操作,所以我想我也会分享您如何在 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
于 2012-12-19T14:23:41.647 回答
0

您也可以通过强制转换从 LINQ 查询中获取字典:

var d2 = (Dictionary<string, string>)q;

这适用于 Visual Studio 2013。

于 2018-04-05T11:47:12.203 回答