【问题标题】:How to use local variables in a lambda expression如何在 lambda 表达式中使用局部变量
【发布时间】:2013-09-10 13:19:58
【问题描述】:

我有 2 个类的类型的列表对象,

 class person
    {
        public string id { get; set; }
        public string name { get; set; }
    }

List<person> pr = new List<person>();
pr.Add(new person { id = "2", name = "rezoan" });
pr.Add(new person { id = "5", name = "marman" });
pr.Add(new person { id = "3", name = "prithibi" });

List<person> tem = new List<person>();
tem.Add(new person { id = "1", name = "rezoan" });
tem.Add(new person { id = "2", name = "marman" });
tem.Add(new person { id = "1", name = "reja" });
tem.Add(new person { id = "3", name = "prithibi" });
tem.Add(new person { id = "3", name = "prithibi" });

现在我必须从 "pr" ListObject 中获取 no entry 或 odd number of entries 在 中的所有 id >“tem” ListObejct。使用 lamda。

为此我使用过,

HashSet<string> inconsistantIDs = new HashSet<string>(pr.Select(p => p.id).Where(p => tem.FindAll(t => t.id == p).Count == 0 || tem.FindAll(t => t.id == p).Count % 2 != 0));

而且效果很好。

但你可以从代码中看到我已经使用 tem.FindAll(t => t.id == p).Count 两次来与 ==0 比较和 %2!=0。

有没有办法使用一次 tem.FindAll(t => t.id == p).Count 和 将其保存到临时变量中,然后将此变量与 ==0 和 %2!=0。

更简单地说,我只想在这里为两个条件使用一次。

【问题讨论】:

  • 请不要将主题用作“xxx中面临的问题”,这将是google-link。

标签: c# linq list lambda


【解决方案1】:

Use a statement lambda instead of an expression lambda

var inconsistantIDs = new HashSet<string>(
           pr.Select(p => p.id).Where(p => 
                  {
                    var count = tem.FindAll(t => t.id == p).Count;
                    return count == 0 || count % 2 != 0;
                  }
           ));

【讨论】:

  • 你这行得通。但是“count .Count % 2 != 0”应该是“count% 2 != 0”。你能纠正一下吗? @Ahmed KRAIEM
  • 我会使用Count() 而不是FindAll。前者需要为每个人创建一个新的集合。
  • @Rezoan 已更正。 @蒂姆这是真的。 var count = tem.Count(t =&gt; t.id == p);
【解决方案2】:

也许很简单:

var query = pr.Where(p => { int c = tem.Count(p2 => p.id == p2.id); return c == 0 || c % 2 != 0; });

返回两个人:

2   "rezoan"
5   "marman"

【讨论】:

    【解决方案3】:

    除了语句 lambda,您还可以使用 let clause:

    HashSet<string> inconsistantIDs = new HashSet<string>(
        from p in pr
        let count = tem.FindAll(t => t.id == p).Count
        where count == 0 || count % 2 != 0
        select p.id
    );
    

    【讨论】:

      【解决方案4】:
      HashSet<string> inconsistantIDs = new HashSet<string>(
          pr.Select(p => new { Id = p.id, Cnt = tem.FindAll(t => t.id == p.id).Count() })
              .Where(p => p.Cnt == 0 || p.Cnt % 2 != 0)
              .Select(p => p.Id);
      

      【讨论】:

      • 谢谢,但它在“t.id == p”和“.Count()”上给了我错误应该是“.Count”。你能看看这个问题吗?
      • 已修复。但是,如果您不理解,我不会使用此代码。
      【解决方案5】:

      附带说明,严格来说性能方面,如果您创建每个 ID 到其计数的哈希映射,然后在循环中搜索它,您将获得更好的性能。

      现在你有一个O(n*m) 算法,它会被简化为O(n+m):

      // create a map (id -> count), O(m) operation
      var dictionary = new Dictionary<string, int>();
      foreach (var p in tem)
      {
          var counter = 0;
          dictionary.TryGetValue(p.id, out counter);
          counter++;
          dictionary[p.id] = counter;
      }
      
      // search the map, O(n) operation
      var results = new HashSet<string>();
      foreach (var p in pr)
      {
          var counter = 0;
          dictionary.TryGetValue(p.id, out counter);
          if (counter == 0 || counter % 2 != 0)
              results.Add(p.id);
      }
      

      【讨论】:

        猜你喜欢
        • 2018-12-07
        • 1970-01-01
        • 1970-01-01
        • 2015-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多