我有两个类型的列表对象,
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" });
现在我必须从&#34; pr&#34; ListObject获取所有ID 无条目或奇数条目在&#34; tem&#34; 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 =&gt; t.id == p).Count 两次使用 == 0 和%2!= 0 。
有没有办法使用 tem.FindAll(t =&gt; t.id == p).Count 一次 将它保存到临时变量,然后将此变量与。进行比较 == 0 和%2!= 0 。
更简单地说,我只想在这里使用一次两种情况。
答案 0 :(得分:14)
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;
}
));
答案 1 :(得分: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"
答案 2 :(得分: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
);
答案 3 :(得分: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);
答案 4 :(得分: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);
}