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

发布于 2024-08-08 18:58:33 字数 375 浏览 4 评论 0原文

我有一个类 Items ,其属性(Id、Name、Code、Price)。

Items 列表中填充有重复的项目。

例如:

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

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

I have a class Items with properties (Id, Name, Code, Price).

The List of Items is populated with duplicated items.

For ex.:

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

How to remove the duplicates in the list using linq?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

故笙诉离歌 2024-08-15 18:58:33
var distinctItems = items.GroupBy(x => x.Id).Select(y => y.First());
var distinctItems = items.GroupBy(x => x.Id).Select(y => y.First());
金兰素衣 2024-08-15 18:58:33
var distinctItems = items.Distinct();

要仅匹配某些属性,请创建一个自定义相等比较器,例如:

class DistinctItemComparer : IEqualityComparer<Item> {

    public bool Equals(Item x, Item y) {
        return x.Id == y.Id &&
            x.Name == y.Name &&
            x.Code == y.Code &&
            x.Price == y.Price;
    }

    public int GetHashCode(Item obj) {
        return obj.Id.GetHashCode() ^
            obj.Name.GetHashCode() ^
            obj.Code.GetHashCode() ^
            obj.Price.GetHashCode();
    }
}

然后像这样使用它:

var distinctItems = items.Distinct(new DistinctItemComparer());
var distinctItems = items.Distinct();

To match on only some of the properties, create a custom equality comparer, e.g.:

class DistinctItemComparer : IEqualityComparer<Item> {

    public bool Equals(Item x, Item y) {
        return x.Id == y.Id &&
            x.Name == y.Name &&
            x.Code == y.Code &&
            x.Price == y.Price;
    }

    public int GetHashCode(Item obj) {
        return obj.Id.GetHashCode() ^
            obj.Name.GetHashCode() ^
            obj.Code.GetHashCode() ^
            obj.Price.GetHashCode();
    }
}

Then use it like this:

var distinctItems = items.Distinct(new DistinctItemComparer());
彩虹直至黑白 2024-08-15 18:58:33

如果有什么东西导致您的 Distinct 查询失败,您可能需要查看 MoreLinq 并使用 DistinctBy 运算符并按 id 选择不同的对象。

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

If there is something that is throwing off your Distinct query, you might want to look at MoreLinq and use the DistinctBy operator and select distinct objects by id.

var distinct = items.DistinctBy( i => i.Id );
画尸师 2024-08-15 18:58:33

这就是我能够使用 Linq 进行分组的方式。希望有帮助。

var query = collection.GroupBy(x => x.title).Select(y => y.FirstOrDefault());

This is how I was able to group by with Linq. Hope it helps.

var query = collection.GroupBy(x => x.title).Select(y => y.FirstOrDefault());
睫毛溺水了 2024-08-15 18:58:33

通用扩展方法:

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

An universal extension method:

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

Example of usage:

var lstDst = lst.DistinctBy(item => item.Key);
最冷一天 2024-08-15 18:58:33

您可以使用三个选项来删除列表中的重复项:

  1. 使用自定义相等比较器,然后使用 Distinct(new DistinctItemComparer()) 作为 @Christian Hayter 提到过。
  2. 使用GroupBy,但请注意,在GroupBy中,您应该按所有列进行分组,因为如果您仅按Id分组,则不会。不要总是删除重复的项目。例如,考虑以下示例:

    列表<项目>; a = 新列表<项目>;
    {
        新商品{Id = 1,名称 =“Item1”,代码 =“IT00001”,价格 = 100},
        新商品{Id = 2,名称 =“Item2”,代码 =“IT00002”,价格 = 200},
        新商品{Id = 3,名称 =“Item3”,代码 =“IT00003”,价格 = 150},
        新商品{Id = 1,名称 =“Item1”,代码 =“IT00001”,价格 = 100},
        新商品{Id = 3,名称 =“Item3”,代码 =“IT00003”,价格 = 150},
        新商品{Id = 3,名称 =“Item3”,代码 =“IT00004”,价格 = 250}
    };
    var uniqueItems = a.GroupBy(x => x.Id).Select(y => y.First());
    

    该分组的结果将是:

    {Id = 1,名称 =“Item1”,代码 =“IT00001”,价格 = 100}
    {Id = 2,名称 =“Item2”,代码 =“IT00002”,价格 = 200}
    {Id = 3,名称 =“Item3”,代码 =“IT00003”,价格 = 150}
    

    这是不正确的,因为它认为 {Id = 3, Name = "Item3", Code = "IT00004", Price = 250} 是重复的。所以正确的查询是:

    vardistinctItems = a.GroupBy(c => new { c.Id , c.Name , c.Code , c.Price})
                         .Select(c => c.First()).ToList();
    

    3.重写item类中的EqualGetHashCode

    公共类项目
    {
        公共 int Id { 得到;放; }
        公共字符串名称{获取;放; }
        公共字符串代码{获取;放; }
        公共 int 价格 { 得到;放; }
    
        公共覆盖布尔等于(对象obj)
        {
            if (!(obj 是 Item))
                返回假;
            项目 p = (项目)obj;
            return (p.Id == Id && p.Name == 名称 && p.Code == 代码 && p.Price == 价格);
        }
        公共重写 int GetHashCode()
        {
            return String.Format("{0}|{1}|{2}|{3}", ID, 名称, 代码, 价格).GetHashCode();
        }
    }
    

    然后你可以像这样使用它:

    vardistinctItems = a.Distinct();
    

You have three option here for removing duplicate item in your List:

  1. Use a a custom equality comparer and then use Distinct(new DistinctItemComparer()) as @Christian Hayter mentioned.
  2. 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();
    
烟花易冷人易散 2024-08-15 18:58:33

使用 Distinct() 但请记住,它使用默认的相等比较器来比较值,因此如果您想要除此之外的任何内容,您需要实现自己的比较器。

请参阅 http://msdn.microsoft.com/en-us/library/bb348436 .aspx 为例。

Use Distinct() but keep in mind that it uses the default equality comparer to compare values, so if you want anything beyond that you need to implement your own comparer.

Please see http://msdn.microsoft.com/en-us/library/bb348436.aspx for an example.

奶茶白久 2024-08-15 18:58:33

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

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

Try this extension method out. Hopefully this could help.

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

Usage:

var outputList = sourceList.DistinctBy(x => x.TargetProperty);
是伱的 2024-08-15 18:58:33
List<Employee> employees = new List<Employee>()
{
    new Employee{Id =1,Name="AAAAA"}
    , new Employee{Id =2,Name="BBBBB"}
    , new Employee{Id =3,Name="AAAAA"}
    , new Employee{Id =4,Name="CCCCC"}
    , new Employee{Id =5,Name="AAAAA"}
};

List<Employee> duplicateEmployees = employees.Except(employees.GroupBy(i => i.Name)
                                             .Select(ss => ss.FirstOrDefault()))
                                            .ToList();
List<Employee> employees = new List<Employee>()
{
    new Employee{Id =1,Name="AAAAA"}
    , new Employee{Id =2,Name="BBBBB"}
    , new Employee{Id =3,Name="AAAAA"}
    , new Employee{Id =4,Name="CCCCC"}
    , new Employee{Id =5,Name="AAAAA"}
};

List<Employee> duplicateEmployees = employees.Except(employees.GroupBy(i => i.Name)
                                             .Select(ss => ss.FirstOrDefault()))
                                            .ToList();
π浅易 2024-08-15 18:58:33

另一种解决方法,不美观但有效。

我有一个 XML 文件,其中包含一个名为“MEMDES”的元素,具有两个属性“GRADE”和“SPD”来记录 RAM 模块信息。
SPD中有很多重复的项目。

这是我用来删除重复项的代码:

IEnumerable<XElement> MList =
    from RAMList in PREF.Descendants("MEMDES")
    where (string)RAMList.Attribute("GRADE") == "DDR4"
    select RAMList;

List<string> sellist = new List<string>();

foreach (var MEMList in MList)
{
    sellist.Add((string)MEMList.Attribute("SPD").Value);
}

foreach (string slist in sellist.Distinct())
{
    comboBox1.Items.Add(slist);
}

Another workaround, not beautiful but working.

I have an XML file with an element called "MEMDES" with two attributes "GRADE" and "SPD" to record the RAM module information.
There is a lot of duplicate items in SPD.

So here is the code I use to remove the duplicated items:

IEnumerable<XElement> MList =
    from RAMList in PREF.Descendants("MEMDES")
    where (string)RAMList.Attribute("GRADE") == "DDR4"
    select RAMList;

List<string> sellist = new List<string>();

foreach (var MEMList in MList)
{
    sellist.Add((string)MEMList.Attribute("SPD").Value);
}

foreach (string slist in sellist.Distinct())
{
    comboBox1.Items.Add(slist);
}
緦唸λ蓇 2024-08-15 18:58:33

当您不想编写 IEqualityComparer 时,您可以尝试以下操作。

 class Program
{

    private static void Main(string[] args)
    {

        var items = new List<Item>();
        items.Add(new Item {Id = 1, Name = "Item1"});
        items.Add(new Item {Id = 2, Name = "Item2"});
        items.Add(new Item {Id = 3, Name = "Item3"});

        //Duplicate item
        items.Add(new Item {Id = 4, Name = "Item4"});
        //Duplicate item
        items.Add(new Item {Id = 2, Name = "Item2"});

        items.Add(new Item {Id = 3, Name = "Item3"});

        var res = items.Select(i => new {i.Id, i.Name})
            .Distinct().Select(x => new Item {Id = x.Id, Name = x.Name}).ToList();

        // now res contains distinct records
    }



}


public class Item
{
    public int Id { get; set; }

    public string Name { get; set; }
}

When you don't want to write IEqualityComparer you can try something like following.

 class Program
{

    private static void Main(string[] args)
    {

        var items = new List<Item>();
        items.Add(new Item {Id = 1, Name = "Item1"});
        items.Add(new Item {Id = 2, Name = "Item2"});
        items.Add(new Item {Id = 3, Name = "Item3"});

        //Duplicate item
        items.Add(new Item {Id = 4, Name = "Item4"});
        //Duplicate item
        items.Add(new Item {Id = 2, Name = "Item2"});

        items.Add(new Item {Id = 3, Name = "Item3"});

        var res = items.Select(i => new {i.Id, i.Name})
            .Distinct().Select(x => new Item {Id = x.Id, Name = x.Name}).ToList();

        // now res contains distinct records
    }



}


public class Item
{
    public int Id { get; set; }

    public string Name { get; set; }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文