C# 连接两个列表,比较它们的元素属性

C# 连接两个列表,比较它们的元素属性,c#,linq,C#,Linq,算法是这样的。 加入两个列表。如果列表中的元素具有相同的ID,请按ChangeDate对它们进行比较,并取日期较大的ond。如果ChangeDate相等,则取其中任何一个,但不能同时取两者。 也许将两个列表合并起来比用lambda过滤它们更容易。我试过了,但总是得出一些难看的代码:/ 有人知道吗?合并两个列表,按降序日期排序。现在,您需要获取排序列表中每个id的第一个出现处。类似的内容如何 Person { ID= 1, Name = "Peter", ChangeDate= "2011

算法是这样的。 加入两个列表。如果列表中的元素具有相同的ID,请按ChangeDate对它们进行比较,并取日期较大的ond。如果ChangeDate相等,则取其中任何一个,但不能同时取两者。 也许将两个列表合并起来比用lambda过滤它们更容易。我试过了,但总是得出一些难看的代码:/


有人知道吗?

合并两个列表,按降序日期排序。现在,您需要获取排序列表中每个id的第一个出现处。

类似的内容如何

    Person { ID= 1, Name = "Peter", ChangeDate= "2011-10-21" },
    Person { ID= 2, Name = "John",  ChangeDate= "2011-10-22" },
    Person { ID= 3, Name = "Mikey", ChangeDate= "2011-10-24" },
    Person { ID= 4, Name = "Dave",  ChangeDate= "2011-10-24" }
    Person { ID= 5, Name = "Larry", ChangeDate= "2011-10-27" }
使用系统;
使用System.Collections.Generic;
使用System.Linq;
公共阶层人士
{
公共int ID;
公共字符串名称;
公共日期时间变更日期;
}
公共类人员比较:IEqualityComparer
{
公共bool等于(人员p1、人员p2)
{
返回p1.ID==p2.ID;
}
公共int GetHashCode(个人p)
{
返回p.ID.GetHashCode();
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var list1=新列表
{
新人{ID=1,Name=“Peter”,ChangeDate=DateTime.Parse(“2011-10-21”)},
新人{ID=2,Name=“John”,ChangeDate=DateTime.Parse(“2011-10-22”)},
新人{ID=3,Name=“Mike”,ChangeDate=DateTime.Parse(“2011-10-23”)},
新人{ID=4,Name=“Dave”,ChangeDate=DateTime.Parse(“2011-10-24”)}
};
var list2=新列表
{
新人{ID=1,Name=“Pete”,ChangeDate=DateTime.Parse(“2011-10-21”)},
新人{ID=2,Name=“Johny”,ChangeDate=DateTime.Parse(“2011-10-20”)},
新人{ID=3,Name=“Mikey”,ChangeDate=DateTime.Parse(“2011-10-24”)},
新人{ID=5,Name=“Larry”,ChangeDate=DateTime.Parse(“2011-10-27”)}
};
var pc=新的个人比较者();
var combined=list1.Join(list2,p=>p.ID,p=>p.ID,(p1,p2)=>p2.ChangeDate>p1.ChangeDate?p2:p1)
.Union(列表1.除外(列表2,pc))
.Union(列表2.除(列表1,pc)外);
foreach(组合中的var p)
{
Console.WriteLine(p.ID+“”+p.Name+“”+p.ChangeDate);
}
}
}

您可以将它们串联并排序,然后获得不同的值:

using System;
using System.Collections.Generic;
using System.Linq;

public class Person
{
    public int ID;
    public string Name;
    public DateTime ChangeDate;
}

public class PersonComparer : IEqualityComparer<Person>
{
    public bool Equals(Person p1, Person p2)
    {
        return p1.ID == p2.ID;
    }

    public int GetHashCode(Person p)
    {
        return p.ID.GetHashCode();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var list1 = new List<Person>
        {
            new Person { ID = 1, Name = "Peter", ChangeDate = DateTime.Parse("2011-10-21") },
            new Person { ID = 2, Name = "John",  ChangeDate = DateTime.Parse("2011-10-22") },
            new Person { ID = 3, Name = "Mike",  ChangeDate = DateTime.Parse("2011-10-23") },
            new Person { ID = 4, Name = "Dave",  ChangeDate = DateTime.Parse("2011-10-24") }
        };

        var list2 = new List<Person>
        {
            new Person { ID = 1, Name = "Pete",  ChangeDate = DateTime.Parse("2011-10-21") },
            new Person { ID = 2, Name = "Johny", ChangeDate = DateTime.Parse("2011-10-20") },
            new Person { ID = 3, Name = "Mikey", ChangeDate = DateTime.Parse("2011-10-24") },
            new Person { ID = 5, Name = "Larry", ChangeDate = DateTime.Parse("2011-10-27") }
        };

        var pc = new PersonComparer();
        var combined = list1.Join(list2, p => p.ID, p => p.ID, (p1,p2) => p2.ChangeDate > p1.ChangeDate ? p2 : p1)
                            .Union(list1.Except(list2, pc))
                            .Union(list2.Except(list1, pc));

        foreach(var p in combined)
        {
            Console.WriteLine(p.ID + " " + p.Name + " " + p.ChangeDate);
        }
    }
}
类PersonIdEqualityComparer:IEqualityComparer
{
公共布尔等于(人x,人y)
{
返回x.ID==y.ID;
}
public int GetHashCode(个人)
{
返回人员ID;
}
}
var result=list1.Concat(list2)
.OrderByDescending(i=>DateTime.Parse(i.ChangeDate))//最近的第一个
.Distinct(新PersonIdEqualityComparer())
;
这假设
Distinct
将从每个集合中取出遇到的第一个项目,而不是任意项目。考虑到它可能只是在遍历集合时将它们插入一个
HashSet
,这对我来说似乎是合理的

它也不会进行错误检查。如果任何值可能为null,或者
ChangeDate
可能无效,则此代码将抛出异常。如果这可能是一个问题,我建议您在传入数据之前检查数据,并在
PersonIdEqualityComparer
类中执行错误检查。

LINQ

class PersonIdEqualityComparer : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {
        return x.ID == y.ID;
    }

    public int GetHashCode(Person person)
    {
        return person.ID;
    }
}

var result = list1.Concat(list2)
    .OrderByDescending(i => DateTime.Parse(i.ChangeDate)) // Most recent first
    .Distinct(new PersonIdEqualityComparer())
    ;

如果可以的话,我会使用
DateTime
而不是字符串值。非常感谢。我已立即应用了解决方案,但忘了标记anwser。对不起,再次感谢!
class PersonIdEqualityComparer : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {
        return x.ID == y.ID;
    }

    public int GetHashCode(Person person)
    {
        return person.ID;
    }
}

var result = list1.Concat(list2)
    .OrderByDescending(i => DateTime.Parse(i.ChangeDate)) // Most recent first
    .Distinct(new PersonIdEqualityComparer())
    ;
var q = from person in list1.Concat(list2)
        group person by person.ID into g
        select g.OrderByDescending(p => p.ChangeDate).First();