从List< Object>中删除重复项.使用LINQ
这个问题很简单,在SO中进行简单的搜索就可以找到许多类似的问题,但是我仍在努力寻找答案.
The question is straightforward and a simple search in SO gives a number of similar questions but I'm still struggling to get an answer for this.
我想根据它们具有的所有属性从List<Column> columns
中删除重复的对象. Column
类本身具有List<string>
属性,这是我认为可能在GetHashCode()
或Equals
部分出现问题的地方.
I want to remove the duplicate objects from List<Column> columns
based on all the properties they have. The Column
class itself has a List<string>
property and this is where I think I have problems maybe in the GetHashCode()
or Equals
part.
这是我编写的完整代码,但没有得到正确的结果.例如,在下面的代码中,我想删除column3,因为它在各个方面都与column1相同.
Here is the full code I've written but I'm not getting the correct results. For example in the code below, I want to remove column3 because it is the same as column1 in every aspect.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Arrays
{
public class ColumnList
{
public static void RemoveDuplicateColumnTypes()
{
// define columns
var column1 = new Column
{
StartElevation = 0,
EndElevation = 310,
ListOfSections = new List<string> { "C50", "C40" }
};
var column2 = new Column
{
StartElevation = 0,
EndElevation = 310,
ListOfSections = new List<string> { "C50", "C30" }
};
var column3 = new Column
{
StartElevation = 0,
EndElevation = 310,
ListOfSections = new List<string> { "C50", "C40"}
};
// list of columns
var columns = new List<Column> { column1, column2, column3 };
var result = columns.Distinct(new ColumnListComparer());
}
}
public class ColumnListComparer : IEqualityComparer<Column>
{
public bool Equals(Column x, Column y)
{
if (x == null || y == null) return false;
if (Math.Abs(x.StartElevation - y.StartElevation) < 0.001 &&
Math.Abs(x.EndElevation - y.EndElevation) < 0.001 &&
x.ListOfSections.SequenceEqual(y.ListOfSections))
{
return true;
}
return false;
}
public int GetHashCode(Column obj)
{
return obj.StartElevation.GetHashCode() ^
obj.EndElevation.GetHashCode() ^
obj.ListOfSections.GetHashCode();
}
}
public class Column
{
public double StartElevation { get; set; }
public double EndElevation { get; set; }
public List<string> ListOfSections { get; set; }
}
}
列表的哈希码不匹配.因此,整个哈希码将不匹配.
The hash code for the lists is not going to match. So the whole hash code won't match.
尝试一下:
public int GetHashCode(Column obj)
{
return 42;
}
如果对象相等,则哈希码必须相等.通常,返回固定数字并不理想,但从字面上看是有效的.为什么是42?搭便车的爱好者.
Hash codes must be equal if the objects are equal. It is not ideal in general to return a fixed number, but it is entitily valid. Why 42? Hitch hikers fan.
如果这行得通,那么您可以寻找一个更好的哈希函数,该函数实际上使用列表中的某些值.
If that works, then you can look for a better hash function that actually uses some of the values in the list.
只要遵循对象的黄金法则,则使哈希函数的复杂程度取决于您,它们的哈希函数必须相等.
How complex you make the hash function is up to you as long as you follow the golden rule of objects are equal, their hash functions must be equal.
例如,这里是一个仅考虑列表长度的有效哈希函数:
Here is for example a valid hash function that just takes into account the length of the list:
public int GetHashCode(Column obj)
{
return obj.ListOfSections.Count;
}