[英]Compare 2 lists of same object type
I have 2 lists of a specific type, in this case it is List. 我有2种特定类型的列表,在本例中为List。 In the class DataDictionary there is a property called TableName.
在DataDictionary类中,有一个名为TableName的属性。 I have 2 lists with the same type I am trying to compare.
我有2个要比较的相同类型的列表。 I have other properties aswell which I need to hold association with that specific TableName so I can't just compare them separately.
我还有其他属性,需要与该特定TableName保持关联,因此我不能仅将它们进行单独比较。
I need to find a way to compare the TableName in 2 different lists of DataDictionary and then find which ones they don't have in common. 我需要找到一种方法来比较DataDictionary的2个不同列表中的TableName,然后找到它们没有共同点的那些。 From there I then need to compare all the other properties against the 2 items in each list with the same TableName.
然后,从那里,我需要将所有其他属性与每个具有相同TableName的列表中的2个项目进行比较。
I have tried to use the Except IEnumerate solution which works if you just compare the strings directly but I don't know how to keep the association with the object. 我尝试使用Except IEnumerate解决方案,如果您直接比较字符串,但我不知道如何保持与对象的关联,该解决方案将起作用。
List<DataDictionary> ColumnsDataDict = daDD.getTablesandColumnsDataDictionary();
List<DataDictionary> ColumnsWizard = daWiz.getColumnsWizard();
var newlist = ColumnsWizard.Except(ColumnsDataDict);
foreach(DataDictionary item in newlist)
{
Console.WriteLine(item.TableName);
}
Here is the DataDictionary
class: 这是
DataDictionary
类:
public string TableName { get; set; }
public string Description { get; set; }
public string TableID { get; set; }
public string ColumnDesc { get; set; }
public string ColumnName { get; set; }
This directly compares the objects, but I just want to compare the TableName property in my DataDictionary class. 这将直接比较对象,但是我只想比较DataDictionary类中的TableName属性。 I want this to then get a list of objects that doesn't have the same table name in each list.
然后,我希望它获得在每个列表中没有相同表名的对象的列表。 Any help is appreciated, thanks!
任何帮助表示赞赏,谢谢!
I don't believe your problem can be solved with LINQ
alone and there for I would recommend using a good old loop
. 我不相信单独使用
LINQ
就能解决您的问题,因为我建议您使用一个良好的旧loop
。
If you want to compare two lists, you will have to use two loops
nested in one another. 如果要比较两个列表,则必须使用彼此嵌套的两个
loops
。
Like this: 像这样:
public class Program
{
public static void Main()
{
var listA = new List<Foo>() {
new Foo() { TableName = "Table A", Value = "Foo 1" },
new Foo() { TableName = "Table B", Value = "Foo 1" },
};
var listB = new List<Foo>() {
new Foo() { TableName = "Table A", Value = "Foo 10" },
new Foo() { TableName = "Table C", Value = "Foo 12" },
};
foreach (var itemA in listA)
{
foreach (var itemB in listB)
{
if (itemA.TableName == itemB.TableName)
{
Console.WriteLine($"ItemA's Value: {itemA.Value}");
Console.WriteLine($"ItemB's Value: {itemB.Value}");
}
}
}
}
}
public class Foo
{
public string TableName { get; set; }
public string Value { get; set; }
}
At the position where I am printing the values of itemA
and itemB
you can compare your objects and find the difference between them. 在我打印
itemA
和itemB
值的itemA
,您可以比较对象并找出它们之间的差异。
So instead of: 所以代替:
Console.WriteLine($"ItemA's Value: {itemA.Value}");
Console.WriteLine($"ItemB's Value: {itemB.Value}");
Maybe something like this: 也许是这样的:
if (itemA.Value != itemB.Value) //extend the `if` with all the properties you want to compare
{
Console.WriteLine($"ItemA's Value isn't equal to ItemB's Value");
}
If you need to check if listA
doesn't have an entry in listB
then you can extend the inner loop like this: 如果您需要检查,如果
listA
没有一个条目中的listB
则可以延长内循环是这样的:
foreach (var itemA in listA)
{
var found = false;
foreach (var itemB in listB)
{
if (itemA.TableName == itemB.TableName)
{
found = true;
}
}
if (found == false)
{
Console.WriteLine("ItemA's TableName wasn't found in listB");
}
}
SOLUTION: 解:
// Merges both objects
List<DataDictionary> duplicatesRemovedLists = ColumnsDataDict.Concat (ColumnsWizard).ToList ();
// Removes common objects based on its property value (eg: TableName)
foreach (var cddProp in ColumnsDataDict) {
foreach (var cwProp in ColumnsWizard) {
if ((cddProp.TableName == cwProp.TableName)) {
duplicatesRemovedLists.Remove (cddProp);
duplicatesRemovedLists.Remove (cwProp);
}
}
}
// Prints expected output
foreach (DataDictionary item in duplicatesRemovedLists) Console.WriteLine (item.TableName);
You can use several LINQ methods implementing a customer IEqualityComparer
. 您可以使用几种LINQ方法来实现客户
IEqualityComparer
。 For instance having a comparer for the property TableName
: 例如,具有属性
TableName
的比较器:
public class TableNameEqualityComparer : IEqualityComparer<DataDictionary>
{
public bool Equals(DataDictionary x, DataDictionary y)
{
if (x == null && y == null)
{
return true;
}
return x != null && y != null && x.TableName == y.TableName;
}
public int GetHashCode(DataDictionary obj)
{
return obj?.TableName?.GetHashCode() ?? 0;
}
}
Two instances returning
true
for theEquals
method must return the same value forGetHashCode
.为
Equals
方法返回true
两个实例必须为GetHashCode
返回相同的值 。
Just make an instance of your custom comparer. 只需创建您的自定义比较器的实例即可。
var listA = new List<DataDictionary>()
{
new DataDictionary() {TableName = "Table A"},
new DataDictionary() {TableName = "Table B"},
};
var listB = new List<DataDictionary>()
{
new DataDictionary() {TableName = "Table A"},
new DataDictionary() {TableName = "Table C"},
};
var tableNameComparer = new TableNameEqualityComparer();
And then use it with different LINQ methods: 然后将其与其他LINQ方法一起使用:
// A - B
var listAExceptB = listA.Except(listB, tableNameComparer);
Assert.Collection(listAExceptB,
x => Assert.Equal("Table B", x.TableName));
// B - A
var listBExceptA = listB.Except(listA, tableNameComparer);
Assert.Collection(listBExceptA,
x => Assert.Equal("Table C", x.TableName));
// A ∩ B
var listIntersect = listA.Intersect(listB, tableNameComparer);
Assert.Collection(listIntersect,
x => Assert.Equal("Table A", x.TableName));
// A ∪ B
var listUnion = listA.Union(listB, tableNameComparer);
Assert.Collection(listUnion,
x => Assert.Equal("Table A", x.TableName),
x => Assert.Equal("Table B", x.TableName),
x => Assert.Equal("Table C", x.TableName));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.