在两个具有相同属性值的列表中选择两个比较器

时间:2019-02-18 19:31:54

标签: c# linq lambda

我想比较两个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.CandidateCp.CandidateC'并输出类似以下消息:

 $"Previous Name: {p.CandidateC.Name} to New Name: {n.CandidateC.Name}"

将提供任何帮助。

2 个答案:

答案 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();