我想删除所有重复项
您尚未定义两个示例对象何时“重复”。我猜,您的意思是,如果两个示例对象的属性Name 和Comment 具有相同的值,那么它们就是重复的。
通常您可以使用Enumerable.GroupBy 的重载之一来查找重复项。使用带有参数resultSelector 的重载来准确定义您想要的结果。
IEnumerable<Example> examples = ...
var result = examples.GroupBy(
// key: Name-Comment
example => new
{
Name = example.Name,
Comment = example.Comment,
}
// parameter resultSelector: for every Name/Comment combination and all
// Examples with this Name/Comment combination make one new example:
(nameCommentCombination, examplesWithThisNameCommentCombination) => new Example
{
Name = nameCommentCombination.Name,
Comment = nameCommentCombination.Comment,
// Quantity is the sum of all Quantities of all Examples with this
// Name/Comment combination
Quantity = examplesWithThisNameCommentCombination
.Select(example => example.Quantity)
.Sum(),
});
这仅在您想要精确的字符串相等时才有效。 “你好”和“你好”是否相等?那么“Déjà vu”和“Deja vu”呢?您想要名称和评论不区分大小写吗?那么变音字符呢?
如果您想要的不仅仅是简单的字符串相等,请考虑创建一个 ExampleComparer 类。
class ExampleComparer : EqualityComparer<Example>
{
... // TODO: implement
}
用法如下:
IEnumerable<Example> examples = ...
IEqualityComparer<Example> comparer = ...
var result = examples.GroupBy(example => example, // key
// resultSelector:
(key, examplesWithThisKey) => new Example
{
Name = key.Name,
Comment = key.Comment,
Quantity = examplesWithThiskey.Sum(example => example.Quantity),
},
comparer);
实现 ExampleComparer
class ExampleComparer : EqualityComparer<Example>
{
public static IEqualityComparer<Example> ByNameComment {get;} = new ExampleComparer;
private static IEqualityComparer<string> NameComparer => StringComparer.CurrentCultureIgnoreCase;
private static IEqualityComparer<string> CommentComparer => StringComparer.CurrentCultureIgnoreCase;
我选择了两个单独的字符串比较器,所以如果以后你决定不同的比较,例如名称必须完全匹配,那么你只需要在这里更改它。
public override bool Equals (Example x, Example y)
{
// almost every Equals method starts with the following three lines
if (x == null) return y == null; // true if both null
if (y == null) return false; // false, because x not null
if (Object.ReferenceEquals(x, y)) return true; // same object
// return true if both examples are considered equal:
return NameComparer.Equals(x.Name, y.Name)
&& CommentComparer.Equals(x.Comment, y.Comment);
}
public override int GetHashCode(Example x)
{
if (x == null) return 5447125; // just a number
return NameComparer.GetHashCode(x.Name)
^ CommentComparer.GetHashCode(x.Comment);
}
注意:如果 Name 或 Comment 为 null 或为空,这也将起作用!
我使用了operator ^ (XOR),因为如果只有两个字段需要考虑,它会提供相当好的哈希值。如果您认为绝大多数示例具有唯一名称,请考虑仅检查属性名称:
return NameComparer.GetHashCode(x.Name);
因为方法 Equals 使用 NameComparer 和 CommentComparer 来检查相等性,所以请确保使用相同的 Comparer 来计算 HashCode。