我有一个类项目与属性(Id,名称,代码,价格)。

项目列表中填充了重复的项目。

为例:

1         Item1       IT00001        $100
2         Item2       IT00002        $200
3         Item3       IT00003        $150
1         Item1       IT00001        $100
3         Item3       IT00003        $150

如何使用linq删除列表中的重复项?


当前回答

你有三个选项来删除列表中的重复项:

Use a a custom equality comparer and then use Distinct(new DistinctItemComparer()) as @Christian Hayter mentioned. Use GroupBy, but please note in GroupBy you should Group by all of the columns because if you just group by Id it doesn't remove duplicate items always. For example consider the following example: List<Item> a = new List<Item> { new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100}, new Item {Id = 2, Name = "Item2", Code = "IT00002", Price = 200}, new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}, new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100}, new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}, new Item {Id = 3, Name = "Item3", Code = "IT00004", Price = 250} }; var distinctItems = a.GroupBy(x => x.Id).Select(y => y.First()); The result for this grouping will be: {Id = 1, Name = "Item1", Code = "IT00001", Price = 100} {Id = 2, Name = "Item2", Code = "IT00002", Price = 200} {Id = 3, Name = "Item3", Code = "IT00003", Price = 150} Which is incorrect because it considers {Id = 3, Name = "Item3", Code = "IT00004", Price = 250} as duplicate. So the correct query would be: var distinctItems = a.GroupBy(c => new { c.Id , c.Name , c.Code , c.Price}) .Select(c => c.First()).ToList(); 3.Override Equal and GetHashCode in item class: public class Item { public int Id { get; set; } public string Name { get; set; } public string Code { get; set; } public int Price { get; set; } public override bool Equals(object obj) { if (!(obj is Item)) return false; Item p = (Item)obj; return (p.Id == Id && p.Name == Name && p.Code == Code && p.Price == Price); } public override int GetHashCode() { return String.Format("{0}|{1}|{2}|{3}", Id, Name, Code, Price).GetHashCode(); } } Then you can use it like this: var distinctItems = a.Distinct();

其他回答

如果有一些东西在Distinct查询中被抛出,您可能需要查看MoreLinq并使用DistinctBy操作符并根据id选择不同的对象。

var distinct = items.DistinctBy( i => i.Id );

使用Distinct(),但请记住,它使用默认的相等比较器来比较值,因此如果您想要其他的比较器,则需要实现自己的比较器。

有关示例,请参见http://msdn.microsoft.com/en-us/library/bb348436.aspx。

试试这个扩展方法。希望这能有所帮助。

public static class DistinctHelper
{
    public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
    {
        var identifiedKeys = new HashSet<TKey>();
        return source.Where(element => identifiedKeys.Add(keySelector(element)));
    }
}

用法:

var outputList = sourceList.DistinctBy(x => x.TargetProperty);

你有三个选项来删除列表中的重复项:

Use a a custom equality comparer and then use Distinct(new DistinctItemComparer()) as @Christian Hayter mentioned. Use GroupBy, but please note in GroupBy you should Group by all of the columns because if you just group by Id it doesn't remove duplicate items always. For example consider the following example: List<Item> a = new List<Item> { new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100}, new Item {Id = 2, Name = "Item2", Code = "IT00002", Price = 200}, new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}, new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100}, new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}, new Item {Id = 3, Name = "Item3", Code = "IT00004", Price = 250} }; var distinctItems = a.GroupBy(x => x.Id).Select(y => y.First()); The result for this grouping will be: {Id = 1, Name = "Item1", Code = "IT00001", Price = 100} {Id = 2, Name = "Item2", Code = "IT00002", Price = 200} {Id = 3, Name = "Item3", Code = "IT00003", Price = 150} Which is incorrect because it considers {Id = 3, Name = "Item3", Code = "IT00004", Price = 250} as duplicate. So the correct query would be: var distinctItems = a.GroupBy(c => new { c.Id , c.Name , c.Code , c.Price}) .Select(c => c.First()).ToList(); 3.Override Equal and GetHashCode in item class: public class Item { public int Id { get; set; } public string Name { get; set; } public string Code { get; set; } public int Price { get; set; } public override bool Equals(object obj) { if (!(obj is Item)) return false; Item p = (Item)obj; return (p.Id == Id && p.Name == Name && p.Code == Code && p.Price == Price); } public override int GetHashCode() { return String.Format("{0}|{1}|{2}|{3}", Id, Name, Code, Price).GetHashCode(); } } Then you can use it like this: var distinctItems = a.Distinct();

一个通用的扩展方法:

public static class EnumerableExtensions
{
    public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> enumerable, Func<T, TKey> keySelector)
    {
        return enumerable.GroupBy(keySelector).Select(grp => grp.First());
    }
}

用法示例:

var lstDst = lst.DistinctBy(item => item.Key);