Jak liczyć duplikaty na liście za pomocą LINQ

Mam listę przedmiotów

  • John ID
  • Matt ID
  • John ID
  • Scott ID
  • Matt ID
  • John ID
  • Lucas ID

Chcę wrzucić je z powrotem do takiej listy, co oznacza również, że chcę sortować według największej liczby duplikatów.

  • John ID 3
  • Matt ID 2
  • Scott ID 1
  • Lucas ID 1

Daj mi znać, jak Mogę to zrobić z LINQ i C#.

Thanks All

Edycja 2 Wyświetlanie Kodu:

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

To zapytanie wyświetla następujące wyniki:

  • 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

Daje mi liczbę i imię, ale nie daje mi ID gry....

Powinien wyświetlać:

  • 6 hello World times 234234
  • 2 Witam Świat. 23432432
 65
Author: SpoiledTechie.com, 2009-01-18

5 answers

Możesz użyć "group by" + "orderby". Zobacz LINQ 101 Po szczegóły

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

W odpowiedzi na ten post (usunięty):

Jeśli masz listę niektórych obiektów niestandardowych, musisz użyć custom comparer lub grupować według określonej właściwości.

Również zapytanie nie może wyświetlić wyniku. Pokaż nam kompletny kod, aby uzyskać lepszą pomoc.

Na podstawie Twojej najnowszej aktualizacji:

Masz tę linijkę kodu:

group xx by xx into g

Ponieważ xx jest niestandardowy system obiektów nie wie, jak porównać jeden element z innym. Jak już pisałem, musisz poprowadzić kompilator i podać jakąś właściwość, która będzie używana w porównywaniu obiektów lub dostarczyć Niestandardowy comparer. Oto przykład:

Zauważ, że używam Foo.Name jako klucz - tzn. obiekty będą grupowane na podstawie wartości właściwości Name .

Jest jeden haczyk - traktujesz 2 obiekty jako duplikaty na podstawie ich nazw, ale co z Id ? W moim przykładzie po prostu pobranie identyfikatora pierwszego obiektu w grupie. Jeśli twoje obiekty mają różne identyfikatory, może to być 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);
}
 90
Author: aku,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:17

Nieco krótsza wersja z wykorzystaniem łańcucha metod:

var list = new List<string> {"a", "b", "a", "c", "a", "b"};
var q = list.GroupBy(x => x)
            .Select(g => new {Value = g.Key, Count = g.Count()})
            .OrderByDescending(x=>x.Count);

foreach (var x in q)
{
    Console.WriteLine("Value: " + x.Value + " Count: " + x.Count);
}
 39
Author: CMS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-18 04:25:30

Możesz też zrobić Słownik:

 var list = new List<string> { "a", "b", "a", "c", "a", "b" };
 var result = list.GroupBy(x => x)
            .ToDictionary(y=>y.Key, y=>y.Count())
            .OrderByDescending(z => z.Value);

 foreach (var x in result)
        {
            Console.WriteLine("Value: " + x.Key + " Count: " + x.Value);
        }
 5
Author: Willy David Jr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-24 15:32:08

Inne rozwiązania używają GroupBy. GroupBy jest powolny (przechowuje wszystkie elementy w pamięci) więc napisałem własną metodę CountBy:

public static Dictionary<TKey,int> CountBy<TSource,TKey>(this IEnumerable<TSource> source, Func<TSource,TKey> keySelector)
{
    var countsByKey = new Dictionary<TKey,int>();
    foreach(var x in source)
    {
        var key = keySelector(x);
        if (!countsByKey.ContainsKey(key))
            countsByKey[key] = 0;
        countsByKey[key] += 1;
    }
    return countsByKey;
}
 4
Author: Colonel Panic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-25 18:45:55

Tutaj znajduje się kompletny program proszę sprawdzić to

static void Main(string[] args)
{
    List<string> li = new List<string>();
    li.Add("Ram");
    li.Add("shyam");
    li.Add("Ram");
    li.Add("Kumar");
    li.Add("Kumar");

    var x = from obj in li group obj by obj into g select new { Name = g.Key, Duplicatecount = g.Count() };
    foreach(var m in x)
    {
        Console.WriteLine(m.Name + "--" + m.Duplicatecount);
    }
    Console.ReadLine();
}        
 0
Author: Debendra Dash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-20 09:20:45