7

我有 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" });

现在我必须从“tem” ListObejct中没有条目奇数条目“pr” ListObject 中获取所有 id 。使用拉姆达。

为此,我使用过,

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进行比较。

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

4

5 回答 5

16

使用语句lambda 而不是表达式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;
                  }
           ));
于 2013-09-06T12:27:35.870 回答
4

也许很简单:

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

返回两个人:

2   "rezoan"
5   "marman"
于 2013-09-06T12:31:36.420 回答
4

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

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
);
于 2013-09-06T13:15:27.230 回答
2
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);
于 2013-09-06T12:28:10.887 回答
2

附带说明一下,严格的性能方面,如果您创建每个 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);
}
于 2013-09-06T12:40:54.547 回答