Question

J'ai une classe Person , avec les propriétés Nom et AreaID .

public class Person
{
   public string Name;
   public int AreaID;

   // snip
}

J'ai une liste < Personne > avec le potentiel de centaines d'objets Personne dans la liste. Par exemple, 100 personnes avec AreaID = 1 et 100 personnes avec AreaID = 2

Je souhaite renvoyer une liste distincte de AreaID et le nombre de personnes possédant ce AreaID.

Par exemple, AreaID = 1 Personnes = 100 AreaID = 2 personnes = 100

Était-ce utile?

La solution

On dirait que vous souhaitez grouper par ID de zone, puis:

var groups = from person in persons
             group 1 by person.AreaID into area
             select new { AreaID = area.Key, Persons = area.Count() };

J'utilise le "groupe 1" pour indiquer que je ne me soucie vraiment pas des données de chaque groupe - seulement du nombre et de la clé.

Cela est inefficace en ce sens qu’il doit tamponner tous les résultats dans l’intérêt du regroupement - vous pouvez bien utiliser Reactive LINQ dans .NET 4.0 pour le faire plus efficacement, ou vous pouvez certainement utiliser Pousser LINQ si vous le vouliez. Là encore, pour des ensembles de données relativement petits, peu importe:)

Autres conseils

Utilisez la méthode GroupBy.

var list = ...list of Persons...

var areas = list.GroupBy( p => p.AreaID )
                .Select( g => new {
                    AreaID = g.Key,
                    Count = g.Count()
                 });

Étonnamment, personne n'a conseillé de remplacer est égal à et GetHashCode . Si vous le faites, vous pouvez faire ce qui suit:

 List<Person> unique = personList.Distinct();

Ou même

 List<Person> areaGroup = personList.GroupBy(p => p.AreaID);
 List<Person> area1Count = personList.Where(p => p.AreaID == 1).Count();

Cela vous donne plus de flexibilité, plus besoin de classe anonyme inutile.

return list.GroupBy(p => p.AreaID)
    .Select(g => new { AreaID = g.Key, People = g.Count() });

vous pouvez utiliser list.GroupBy (x = > x.AreaID);

Vous pouvez essayer ceci:

var groups = from person in list
             group person by person.AreaID into areaGroup
             select new {
                 AreaID = areaGroup.Key,
                 Count = areaGroup.Count()
             };
        var people = new List<Person>();

        var q = from p in people
                group p by p.AreaId into g
                select new { Id = g.Key, Total = g.Count() };


        people.Add(new Person { AreaId = 1, Name = "Alex" });
        people.Add(new Person { AreaId = 1, Name = "Alex" });
        people.Add(new Person { AreaId = 2, Name = "Alex" });
        people.Add(new Person { AreaId = 3, Name = "Alex" });
        people.Add(new Person { AreaId = 3, Name = "Alex" });
        people.Add(new Person { AreaId = 4, Name = "Alex" });
        people.Add(new Person { AreaId = 2, Name = "Alex" });
        people.Add(new Person { AreaId = 4, Name = "Alex" });
        people.Add(new Person { AreaId = 1, Name = "Alex" });

        foreach (var item in q)
        {
            Console.WriteLine("AreaId: {0}, Total: {1}",item.Id,item.Total);
        }

Quelque chose comme ça, peut-être?

            List<Person> persons = new List<Person> ();
            persons.Add (new Person (1, "test1"));
            persons.Add (new Person (1, "test2"));
            persons.Add (new Person (2, "test3"));

            var results = 
                persons.GroupBy (p => p.AreaId);

            foreach( var r in results )
            {
                Console.WriteLine (String.Format ("Area Id: {0} - Number of members: {1}", r.Key, r.Count ()));
            }

            Console.ReadLine ();

Au lieu de distinct, utilisez GroupBy , ou la déclaration LINQ plus succincte:

var results = from p in PersonList
              group p by p.AreaID into g
              select new { AreaID=g.Key, Count=g.Count() };

foreach(var item in results)
    Console.WriteLine("There were {0} items in Area {1}", item.Count, item.AreaID);

ToLookup () fera ce que vous voulez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top