如何使用LINQ填充字典?

4
public class Person
{
     public string Email {get; set;}
     public string Name {get; set;}
}

public Report : Dictionary<string, string>
{
     public Report()
     {
         List<Person> list = getData(); // filled with Person's
         var realList = list.Where(x => x.Name != "test");
         foreach( var i in realList)
         {
              this.Add(i.Email,i.Name);
         }
     }

}

我试图简化我的代码以便提出问题。基本上,我有一个Person列表,我想获取该列表的子列表,然后对于子列表中的每个元素,我想将其添加到这个类的字典中。
我的问题:是否有一种方法可以摆脱foreach语句并通过上面的linq语句实现相同的效果。因为对我来说,先遍历列表再遍历子列表似乎很愚蠢。所以在linq语句中,如果x.Name不等于test,则将其添加到字典中是很好的选择。
2个回答

16
我的问题是:有没有一种方法可以摆脱那个foreach语句,并通过上面的linq语句实现相同的效果。因为我觉得两次遍历列表很傻。 在你的代码中,你并没有两次遍历列表-列表只被枚举一次,因为LINQ使用延迟执行。这可能是实现此目的的最佳方式。但是,如果您没有子类化字典并将其封装,您可以使用 ToDictionary 来创建封装的字典:
List<Person> list = getData(); // filled with Person's
Dictionary<string,string> people = list
                                     .Where(x => x.Name != "test")
                                     .ToDictionary(x => x.Email, x => x.Name);

说起来也是,你可以编写 getData().Where(...)。当然,前提是在代码中没有其他地方使用 list - Jim Mischel
好的,一开始我在编辑别人的代码。所以我不知道为什么他们继承了字典类。他们有一个嵌套的for循环。所以根据我所看到的,我认为不需要继承字典,只需使用简单注入器,然后可以使用Linq命令在列表中进行一次搜索来完成所有操作。 - Beastwood
@Beastwood 没错 - 除非你有一个真正好的理由需要这样做,否则我不会继承字典。在那种情况下,封装可能更好...只需根据需要构建字典即可。 - Reed Copsey

0
尽管已经有一些不错的答案说明如何将列表直接转换为字典,但它们并没有真正回答原问题,因为您无法重新分配this变量(对于C#中的类它是只读的),您必须遍历新创建的字典,将其中的元素添加到您的this字典中。
我通常通过将LINQ表达式材料化为List,并使用该列表的ForEach()方法(也接受lambda表达式)来填充另一个结构来解决此问题。
这是示例代码:
     list
        .Where(x => x.Name != "test")             // your condition
        .ToList()                                 // turns expression to list
        .ForEach(a => this.Add(a.Email, a.Name)); // populating dictionary

在调用ToList()之前,您可以设置多个条件,以防您想要排除字典中已经存在的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接