SpoiledTechie.com SpoiledTechie.com - 2 months ago 9
C# Question

How to Count Duplicates in List with LINQ

I have a list of items


  • John ID

  • Matt ID

  • John ID

  • Scott ID

  • Matt ID

  • John ID

  • Lucas ID



I want to shove them back into a list like so which also means I want to sort by the highest number of duplicates.


  • John ID 3

  • Matt ID 2

  • Scott ID 1

  • Lucas ID 1



Let me know how I can do this with LINQ and C#.

Thanks All

EDIT 2 Showing Code:

List<game> inventory = new List<game>();
drinkingforDataContext db = new drinkingforDataContext();
foreach (string item in tbTitle.Text.Split(' '))
{

List<game> getItems = (from dfg in db.drinkingfor_Games
where dfg.game_Name.Contains(tbTitle.Text)
select new game
{
gameName = dfg.game_Name,
gameID = Boomers.Utilities.Guids.Encoder.EncodeURLs(dfg.uid)
}).ToList<game>();

for (int i = 0; i < getItems.Count(); i++)
{
inventory.Add(getItems[i]);
}
}

var items = (from xx in inventory
group xx by xx into g
let count = g.Count()
orderby count descending
select new
{
Count = count,
gameName = g.Key.gameName,
gameID = g.Key.gameID
});

lvRelatedGames.DataSource = items;
lvRelatedGames.DataBind();


This query displays these results:


  • 1 hello world times

  • 1 hello world times

  • 1 Hello World.

  • 1 hello world times

  • 1 hello world times

  • 1 hello world times

  • 1 Hello World.

  • 1 hello world times



It gives me the count and name, but it doesn't give me the ID of the game....

It should display:


  • 6 hello world times 234234

  • 2 Hello World. 23432432


aku aku
Answer

You can use "group by" + "orderby". See LINQ 101 for details

var list = new List<string> {"a", "b", "a", "c", "a", "b"};
var q = from x in list
        group x by x into g
        let count = g.Count()
        orderby count descending
        select new {Value = g.Key, Count = count};
foreach (var x in q)
{
    Console.WriteLine("Value: " + x.Value + " Count: " + x.Count);
}

In response to this post (now deleted):

If you have a list of some custom objects then you need to use custom comparer or group by specific property.

Also query can't display result. Show us complete code to get a better help.

Based on your latest update:

You have this line of code:

group xx by xx into g

Since xx is a custom object system doesn't know how to compare one item against another. As I already wrote, you need to guide compiler and provide some property that will be used in objects comparison or provide custom comparer. Here is an example:

Note that I use Foo.Name as a key - i.e. objects will be grouped based on value of Name property.

There is one catch - you treat 2 objects to be duplicate based on their names, but what about Id ? In my example I just take Id of the first object in a group. If your objects have different Ids it can be a problem.

//Using extension methods
var q = list.GroupBy(x => x.Name)
            .Select(x => new {Count = x.Count(), 
                              Name = x.Key, 
                              ID = x.First().ID})
            .OrderByDescending(x => x.Count);

//Using LINQ
var q = from x in list
        group x by x.Name into g
        let count = g.Count()
        orderby count descending
        select new {Name = g.Key, Count = count, ID = g.First().ID};

foreach (var x in q)
{
    Console.WriteLine("Count: " + x.Count + " Name: " + x.Name + " ID: " + x.ID);
}
Comments