【问题标题】:How to filter on a list of keys in a Dictionary using LINQ如何使用 LINQ 过滤字典中的键列表
【发布时间】:2016-03-10 00:37:08
【问题描述】:

我将这本字典 mappings 声明为 Dictionary<string, HashSet<string>>
我也有这种方法可以对字典中的哈希集进行处理:

public void DoStuff(string key, int iClassId){
    foreach (var classEntry in
             from c in mappings[key]
             where c.StartsWith(iClassId + "(")
             select c)
    {
        DoStuffWithEntry(classEntry);
    }
}

private void DoStuffWithEntry(string classEntry){
    // Do stuff with classEntry here
}

在一种情况下,我需要对映射字典中的多个键执行此操作,我认为最好重写和过滤键列表,而不是为每个键调用 DoStuff 以优化执行。

目前我这样做:

DoStuff("key1", 123);
DoStuff("key2", 123);
DoStuff("key4", 123);
DoStuff("key7", 123);
DoStuff("key11", 123);

逻辑上是这样的,而不是为每个调用 DoStuff(FilterOnKeys 不是一种方法 - 正是我想要的......):

    foreach (var classEntry in
             from c in mappings.FilterOnKeys("key1", "key2", "key4", "key7", "key11")
             where c.StartsWith(iClassId + "(")
             select c)
    {
        DoStuffWithEntry(classEntry);
    }

【问题讨论】:

    标签: c# linq optimization


    【解决方案1】:

    听起来像你想要的:

    string[] keys = { "key1", "key2", ... }
    var query = from key in keys
                from c in mappings[key]
                ...;
    
    foreach (var entry in query)
    {
        ...
    }
    

    (我个人会为查询使用一个单独的变量,只是为了便于阅读 - 我不太热衷于 foreach 循环的声明位变得很大。)

    【讨论】:

    • 这种方法会比我的原始版本执行得更好,还是只是“美化”简化表达式?
    • 化妆品真的很简单。从根本上说,.NET 字典不允许您一次查找多个键。如果您使用的是 LINQ to SQL 或类似的东西,可能会有更好的选择。
    【解决方案2】:

    我正在根据您的要求使用 LINQ

    var temp = eid.Select(i => 
                EmployeeList.ContainsKey(i) 
                ? EmployeeList[i]
                : null
            ).Where(i => i != null).ToList();
    

    完整的 C# 源代码是

    public class Person
    {
        public int EmpID { get; set; }
        public string Name { get; set; }
        public string Department { get; set; }
        public string Gender { get; set; }
    }
    
    void Main()
    {   
        Dictionary<int, Person> EmployeeList = new Dictionary<int, Person>();
        EmployeeList.Add(1, new Person() {EmpID = 1, Name = "Peter", Department = "Development",Gender = "Male"});
        EmployeeList.Add(2, new Person() {EmpID = 2, Name = "Emma Watson", Department = "Development",Gender = "Female"});
        EmployeeList.Add(3, new Person() {EmpID = 3, Name = "Raj", Department = "Development",Gender = "Male"});
        EmployeeList.Add(4, new Person() {EmpID = 4, Name = "Kaliya", Department = "Development",Gender = "Male"});
        EmployeeList.Add(5, new Person() {EmpID = 5, Name = "Keerthi", Department = "Development",Gender = "Female"});
    
        List<int> eid = new List<int>() { 1,3 };
    
        List<Person> SelectedEmployeeList = new List<Person>();
    
        var temp = eid.Select(i => 
                    EmployeeList.ContainsKey(i) 
                    ? EmployeeList[i]
                    : null
                ).Where(i => i != null).ToList();
    
    }
    

    【讨论】:

      【解决方案3】:

      你可以使用这样的东西

      var ids = {1, 2, 3};  
      var query = from item in context.items             
      where ids.Contains(item.id )             
      select item; 
      

      你的情况

      string[] keys = { "key1", "key2", ... }
       var query = from key in keys             
        where ids.Contains(keys  )             
         select key ; 
      

      【讨论】:

        【解决方案4】:

        你可以通过映射链接你的方式 已编辑我错过了一个嵌套级别,他想查询哈希集而不是整个字典

        public void DoStuff(IEnumerable<string> key, int iClassId)
        {
            mappings.Where(i=>key.Contains(i.Key)).ToList().ForEach(obj=>
            {
                foreach (var classEntry in
                     from c in obj.Value
                     where c.StartsWith(iClassId + "(")
                     select c)
                {
                    DoStuffWithEntry(classEntry);
                }
        }
        

        更改了key 参数和from c ... 部分。

        你这样称呼它

        string[] keys = new string[]{"key1", "key2", ... , "keyN"};
        DoStuff(keys, 123);
        

        这应该可以工作

        【讨论】:

        • 这会导致 classEntry 的值成为字典中包含的 HashSet 值——而不是循环遍历 HashSet 的每个值。
        猜你喜欢
        • 1970-01-01
        • 2015-11-03
        • 2018-05-01
        • 1970-01-01
        • 2016-06-27
        • 2020-04-08
        • 2022-12-02
        • 2020-05-21
        • 2020-10-30
        相关资源
        最近更新 更多