比较2个相同对象类型的列表

时间:2019-07-25 12:52:39

标签: c# object

我有2个特定类型的列表,在本例中为List。在DataDictionary类中,有一个名为TableName的属性。我有2个要比较的相同类型的列表。我还有其他属性,需要与该特定TableName保持关联,因此我不能仅将它们进行单独比较。

我需要找到一种方法来比较DataDictionary的2个不同列表中的TableName,然后找到它们没有共同点的那些。然后,从那里我需要将所有其他属性与每个列表中具有相同TableName的2个项目进行比较。

我尝试使用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);
}

这是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; }

这直接比较对象,但是我只想比较DataDictionary类中的TableName属性。然后,我希望它获得在每个列表中没有相同表名的对象的列表。感谢您的任何帮助,谢谢!

3 个答案:

答案 0 :(得分:0)

我不相信仅凭LINQ就能解决您的问题,因为我建议您使用旧的loop

如果要比较两个列表,则必须使用两个彼此嵌套的loops

赞:

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; }
}

在我打印itemAitemB的值的位置,您可以比较对象并找出它们之间的差异。

所以代替:

Console.WriteLine($"ItemA's Value: {itemA.Value}");
Console.WriteLine($"ItemB's Value: {itemB.Value}");

也许是这样的:

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");
}

如果您需要检查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");
    }
}

答案 1 :(得分:0)

解决方案:

// 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);

答案 2 :(得分:0)

您可以使用多种 LINQ 方法来实现客户IEqualityComparer。 例如,具有属性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;
    }
}
  

两个为true方法返回Equals的实例必须返回   GetHashCode相同的值

只需创建您的自定义比较器的实例即可。

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

然后将其与其他 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));