简体   繁体   中英

complex LINQ query

Consider the collection

List<Person> people = new List<Person>
        {
            new Person{Name = "A", SSN="1", Age = 23},
            new Person{Name = "A", SSN="2", Age = 23},
            new Person{Name = "B", SSN="3", Age = 24},
            new Person{Name = "C", SSN="4", Age = 24},
            new Person{Name = "D", SSN="5", Age = 23}
        };

The question is: How can I write a LINQ query to group Person on Age and then count number of person with in each group having the same name?

I tried using group by operator, nested queries all possibilities still could not figure out the exact query.

Regards, Jeez

How about

var ages  = from p in people 
            group p by p.Age into g
            select new { 
                Age = g.Key, 
                Count = g.Count(), 
                Names = from prs in g 
                        group prs by prs.Name
            };

The Names property will have the name as the Key and you can then get Count() for each name.

basically the same as:

var peeps = 
    people.GroupBy(p => p.Age).Select(gp => new
          {
              Aged = gp.Key,
              Count = gp.Count(),
              NameGrp = gp.GroupBy(pers => pers.Name)
          });

jim

List<Person> persons = new List<Person>
{
   new Person{Name = "A", SSN="1", Age = 23},
   new Person{Name = "A", SSN="2", Age = 23},
   new Person{Name = "B", SSN="3", Age = 24},
   new Person{Name = "C", SSN="4", Age = 24},
   new Person{Name = "D", SSN="5", Age = 23}
};
var out1 = persons.GroupBy(p => new { p.Age, p.Name }).Select(s => new { Name = s.Key.Name,age = s.Key.Age, cnt = s.Count() }); ;
System.Threading.Tasks.Parallel.ForEach(out1, item => Console.WriteLine(item.Name + " " + item.age + " " + item.cnt));  

This is no different from grouping by both age and name, including count and optionally order by age and name. LINQ operations on pairs can usually be done by simply using anonymous types like so:

var people = new List<Person> { 
    new Person { FirstName = "John", LastName = "Leidegren", Age = 25 },
    new Person { FirstName = "John", LastName = "Doe", Age = 25 },
    new Person { FirstName = "Not john", LastName = "Doe", Age = 26 },
};

foreach (var g in (from p in people
                   group p by new { p.Age, p.FirstName }))
{
    Console.WriteLine("Count: {0}", g.Count());

    foreach (var person in g.OrderBy(x => x.FirstName))
    {
        Console.WriteLine("FirstName: {0}, LastName: {1}, Age: {2}"
            , person.FirstName
            , person.LastName
            , person.Age);
    }
}

It's very clear what the unique key is here and it can be changed without having to also change the structure of the remaining program.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM