.net 如何编写生成字典的LINQ查询?

deyfvvtc  于 2022-11-26  发布在  .NET
关注(0)|答案(6)|浏览(189)
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〉?

juud5qan

juud5qan1#

您需要指定Dictionary的值

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

oalqel3c2#

一个字典不能包含多个相同的键,所以你应该确保(或知道)不是这种情况。你可以使用GroupBy来确保它:

Dictionary<string, string> dict = pl
        .Where(p => p.Name.First() == 'A')
        .GroupBy(p => p.NickName)
        .ToDictionary(g => g.Key, g => g.First().Name);
7fhtutme

7fhtutme3#

编辑

如果你真的觉得你需要从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

如果您预期重复,那么您也可以创建一个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'
        select p;
var d = q.ToDictionary(p => p.NickName, p => p.Name);

如果存在重复项,do

var d = q.ToLookup(p => p.NickName, p => p.Name);

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

628mspwn

628mspwn4#

请尝试以下操作,将NickName作为键,将Name作为值

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

但请注意,字典不允许重复,因此上面将对具有相同昵称重复记录引发错误也许您希望使用类似于字典但允许重复查找

var d2 = q.ToLookup (p => p.NickName, p=>p.Name);
7fyelxc5

7fyelxc55#

我知道这是用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
n53p2ov0

n53p2ov06#

您也可以透过转型从LINQ查询取得Dictionary:

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

这在Visual Studio 2013上有效。

相关问题