我想比较两个List<Candidate>
,并在Hash
属性中选择两个具有相同值的实体。
public class Candidate : IEquatable<Candidate>
{
public string Name { get; set; }
public String Hash { get; set; }
}
//....
//List with "CandidateA", "CandidateB", "CandidateC" values
List<Candidate> newsCandidate = loadNewsCandidate();
//List with "CandidateC' " , "CandidateD", "CandidateE" values
List<Candidate> previousCandidate = loadPreviousCandidate();
//CandidateC and CandidateC' has same 'Hash' value.
//This return "CandidateC" in newsCandidate
var common = newsCandidate.Where(n => previousCandidate.Any(p => p.Hash.Equals(n.Hash))).ToList();
我想检索List<Tuple<Candidate,Candidate>>
或类似的元素n.CandidateC
和p.CandidateC'
并输出类似以下消息:
$"Previous Name: {p.CandidateC.Name} to New Name: {n.CandidateC.Name}"
将提供任何帮助。
答案 0 :(得分:1)
也许最简单的方法是根据先前的候选者创建一个Dictionary
并查找每个匹配项:
var prevDict = previousCandidate.ToDictionary(pc => pc.Hash);
var ans = newsCandidate.Select(nc => prevDict.TryGetValue(nc.Hash, out var pc) ? new { pc, nc } : null).Where(pcnc => pcnc != null);
如果您不想手动构建自己的Dictionary
,也可以使用LINQ Join
来完成相同的操作:
var ansj = previousCandidate.Join(newsCandidate, pc => pc.Hash, nc => nc.Hash, (pc, nc) => new { pc, nc });
答案 1 :(得分:0)
看来GroupBy
可能有用:
var p = new List<Candidate>
{
new Candidate { Name = "John", Hash = "1" },
new Candidate { Name = "Mike", Hash = "2" }
};
var n = new List<Candidate>
{
new Candidate { Name = "Mike", Hash = "1" },
new Candidate { Name = "John", Hash = "2" }
};
var joined = p.Concat(n).GroupBy(item => item.Hash);
Console.WriteLine(string.Join("\n", joined
.Where(g => g.Count() == 2)
.Select(g => $"Old name {g.First().Name}, New name {g.Last().Name}")));
// Old name John, new name Mike
// Old name Mike, new name John
或只需使用以下内容制作List<Tuple<Candidate, Candidate>>
:
List<Tuple<Candidate, Candidate>> tuple = joined
.Where(g => g.Count() == 2)
.Select(g => new Tuple<Candidate, Candidate>(g.First(), g.Last()))
.ToList();