使用LINQ将此列表列表转换为字典

本文关键字:列表 转换 字典 LINQ 使用 | 更新日期: 2023-09-27 18:28:31

我有一个类:

public class Client
{
    public Client()
    {
        TemplateKeys = new List<int>();
    }
    public List<int> TemplateKeys { get; set; }
}

然后我创建3个实例:

List<Client> clients = new List<Client>();
Client client = new Client();
client.TemplateKeys.Add(1);
client.TemplateKeys.Add(2);
client.TemplateKeys.Add(3);
clients.Add(client);
//..
Client client1 = new Client();
client1.TemplateKeys.Add(1);
client1.TemplateKeys.Add(3);
clients.Add(client1);
//..
Client client2 = new Client();
client2.TemplateKeys.Add(2);
client2.TemplateKeys.Add(4);
clients.Add(client2);

然后我创建了一个字典:

Dictionary<int, string> templatesInUse = new Dictionary<int, string>();

因此,我想做的是将这个clients列表中用户使用的TemplateKeys作为templatesInUse字典的关键字,Distinct()他们和他们,其中现在的值将是string.Empty。这个想法是,一旦我有了密钥,我就要在数据库中查询与决策中每个密钥相关的文本。然后,我将用数据库中的结果替换string.Empty值,我将能够为每个用户使用模板,而不必多次查询数据库中的同一模板。

所以我所做的是首先尝试提取不同的值,我这样做了:

List<int> res = clients.SelectMany(cl => cl.TemplateKeys)
                       .Distinct()
                       .ToList();

现在我想让这个LINQ表达式返回所需的Dictionary<int, string>结果。我看到LINQ已经内置在ToDictionary()扩展方法中,但我找不到用ToDictionary()替换ToList()的方法来获得结果,如下所示:

templatesInUse  = clients.SelectMany(cl => cl.TemplateKeys)
                         .Distinct()
                         .ToDictionary(//tried some things here with no success);

所以我看到几乎所有ToDictionary的例子都使用GroupBy(),尽管我不需要分组,我希望看到不使用它的解决方案。我把我的LINQ改成这样:

templatesInUse = clients.SelectMany(cl => cl.TemplateKeys)
                        .Distinct()
                        .GroupBy(t => t)
                        .ToDictionary(g => g.Key, g.ToString());

它在一定程度上起作用,但不是我想要的string.Empty或只是""值。我得到了一些奇怪的值,这在理论上会起作用,因为这些值会被替换,但我仍然希望得到一个干净。我的意思是,在执行LINQ查询后,我希望得到TemplateKey作为我的Dictionary键,空字符串作为我的值。正如我所提到的,我真的很想知道,也很想知道一种不使用GroupBy()的方法,那就是在使用ToDictionary()时必须这样做吗?

使用LINQ将此列表列表转换为字典

您不需要分组。只需将密钥指定为数字,将值指定为string.Empty.

templatesInUse = clients.SelectMany(cl => cl.TemplateKeys).Distinct()
                 .ToDictionary(x => x, x => string.Empty);