简体   繁体   English

获取2个列表之间的差异

[英]Get the differences between 2 lists

I have two lists ( ListA and ListB ), the type of these lists is the same PersonInfo , the Login field is a unique key. 我有两个列表( ListAListB ),这些列表的类型是相同的PersonInfoLogin字段是唯一的键。

public class PersonInfo
{
    public string Login { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
    public bool Active { get; set; }
}

I'd like compare these two lists : 我想比较这两个列表:

  1. I'd like get a list of items in ListA not available in ListB 我想获得ListA不可用的ListB中的项目列表

  2. For the items available in both lists, I'd like get a list from ListA ( Login field is a unique key) for the item where there is a difference between the two lists. 对于这两个列表中可用的项目,我想从获取列表ListALogin场是一个独特的键)那里是两个列表之间的差异的项目。

Example : if for the Login "MyLogin" in ListA , the value of FirstName does not match with the value in ListB . 例如:如果在Login在“MyLogin” ListA ,价值FirstName不匹配的值ListB The item with "MyLogin" as Login must be part of the result list. “MyLogin”作为Login必须是结果列表的一部分。

Example : if the Age between ListA and ListB for a specific login is different, the item must be part of the result 示例:如果特定登录的ListAListB之间的Age不同,则该项必须是结果的一部分

Thanks. 谢谢。

EDIT 编辑

Try this soltuion for detail difference : Compare two objects and find the differences 尝试这个解决细节差异: 比较两个对象并找出差异


How to: Find the Set Difference Between Two Lists (LINQ) 如何:找到两个列表之间的集合差异(LINQ)

Enumerable.Except Method (IEnumerable, IEnumerable) -Produces the set difference of two sequences by using the default equality comparer to compare values. Enumerable.Except方法(IEnumerable,IEnumerable) -通过使用默认的相等比较器来比较值来产生两个序列的集合差异。

       double[] numbers1 = { 2.0, 2.1, 2.2, 2.3, 2.4, 2.5 };
        double[] numbers2 = { 2.2 };

        IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2);

or 要么

//newList will include all the common data between the 2 lists
List<T> newList = list1.Intersect(list2).ToList<T>();


//differences will be the data not found 
List<T> differences = list1.RemoveAll(a => newList.Contains(a));

or 要么

outer join to get difference 外连接以获得差异

var compare1to2 = from a in 
           from b in driveList2.Where(b => b.property == a.property).DefaultIfEmpty()
                              select a;

To compare objects of custom data type lists, you will need to implement IEquatable in your class and override GetHashCode() 要比较自定义数据类型列表的对象,您需要在类中实现IEquatable并覆盖GetHashCode()

Check this MSDN Link 检查此MSDN链接

Your class 你的班

    public class PersonInfo : IEquatable<PersonInfo>
    {
        public string Login { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public bool Active { get; set; }

        public bool Equals(PersonInfo other)
        {
            //Check whether the compared object is null.
            if (Object.ReferenceEquals(other, null)) return false;

            //Check whether the compared object references the same data.
            if (Object.ReferenceEquals(this, other)) return true;

            //Check whether the properties are equal.
            return Login.Equals(other.Login) && FirstName.Equals(other.FirstName) && LastName.Equals(other.LastName) && Age.Equals(other.Age) && Active.Equals(other.Active);
        }

        public override int GetHashCode()
        {

            int hashLogin = Login == null ? 0 : Login.GetHashCode();

            int hashFirstName = FirstName == null ? 0 : FirstName.GetHashCode();

            int hashLastName = LastName == null ? 0 : LastName.GetHashCode();

            int hashAge = Age.GetHashCode();

            int hashActive = Active.GetHashCode();

            //Calculate the hash code.
            return (hashLogin + hashFirstName + hashLastName) ^ (hashAge + hashActive);
        }
    }

Then here is how you use it (as listed in Pranay's response) 然后是你如何使用它(如Pranay的回应中所列)

            List<PersonInfo> ListA = new List<PersonInfo>() { new PersonInfo { Login = "1", FirstName = "James", LastName = "Watson", Active = true, Age = 21 }, new PersonInfo { Login = "2", FirstName = "Jane", LastName = "Morrison", Active = true, Age = 25 }, new PersonInfo { Login = "3", FirstName = "Kim", LastName = "John", Active = false, Age = 33 } };
            List<PersonInfo> ListB = new List<PersonInfo>() { new PersonInfo { Login = "1", FirstName = "James2222", LastName = "Watson", Active = true, Age = 21 }, new PersonInfo { Login = "3", FirstName = "Kim", LastName = "John", Active = false, Age = 33 } };

            //Get Items in ListA that are not in ListB
            List<PersonInfo> FilteredListA = ListA.Except(ListB).ToList();

            //To get the difference between ListA and FilteredListA (items from FilteredListA will be removed from ListA)
            ListA.RemoveAll(a => FilteredListA.Contains(a));
var list3 = list1.Except(list2).ToList(); //List3 contains what in list1 but not _list2.

Try this for objects comparison and loop around it for List<T> 尝试使用它进行对象比较,并为List<T>循环它

public static void GetPropertyChanges<T>(this T oldObj, T newObj)
{
    Type type = typeof(T);
    foreach (System.Reflection.PropertyInfo pi in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
    {
        object selfValue = type.GetProperty(pi.Name).GetValue(oldObj, null);
        object toValue = type.GetProperty(pi.Name).GetValue(newObj, null);
        if (selfValue != null && toValue != null)
        {
            if (selfValue.ToString() != toValue.ToString())
            {
                //do your code
            }
        }
    }
}

您可以使用LINQ中的Zip()和Intersect()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM