una sumar suma lista con agrupar c# linq group-by

c# - lista - agrupar y sumar en linq



Agrupar por en LINQ (7)

Absolutamente - básicamente quieres:

var results = from p in persons group p.car by p.PersonId into g select new { PersonId = g.Key, Cars = g.ToList() };

O como una expresión sin consulta:

var results = persons.GroupBy( p => p.PersonId, p => p.car, (key, g) => new { PersonId = key, Cars = g.ToList() });

Básicamente, el contenido del grupo (cuando se ve como un IEnumerable<T> ) es una secuencia de cualquier valor que haya en la proyección ( p.car en este caso) presente para la clave dada.

Para obtener más información sobre cómo funciona GroupBy , consulte mi publicación de Edulinq sobre el tema .

(He cambiado el nombre de PersonID a PersonId en la anterior, para seguir las convenciones de nombres de .NET ).

Alternativamente, podrías usar una Lookup :

var carsByPersonId = persons.ToLookup(p => p.PersonId, p => p.car);

A continuación, puede obtener los coches para cada persona muy fácilmente:

// This will be an empty sequence for any personId not in the lookup var carsForPerson = carsByPersonId[personId];

Supongamos que si tenemos una clase como

class Person { internal int PersonID; internal string car ; }

Ahora tengo una lista de esta clase: List<Person> persons;

Ahora esta lista puede tener varias instancias con los mismos ID de persona, por ejemplo:

persons[0] = new Person { PersonID = 1, car = "Ferrari" }; persons[1] = new Person { PersonID = 1, car = "BMW" }; persons[2] = new Person { PersonID = 2, car = "Audi" };

¿Hay alguna manera de que pueda personID por personID y obtener la lista de todos los autos que tiene?

Por ejemplo, el resultado esperado sería

class Result { int PersonID; List<string> cars; }

Así que después de agrupar, obtendría:

results[0].PersonID = 1; List<string> cars = results[0].cars; result[1].PersonID = 2; List<string> cars = result[1].cars;

De lo que he hecho hasta ahora:

var results = from p in persons group p by p.PersonID into g select new { PersonID = g.Key, // this is where I am not sure what to do

¿Podría alguien, por favor, señalarme en la dirección correcta?


He creado un ejemplo de código de trabajo con Sintaxis de consulta y Sintaxis de método. Espero que ayude a los demás :)

También puede ejecutar el código en .Net Fiddle aquí:

using System; using System.Linq; using System.Collections.Generic; class Person { public int PersonId; public string car ; } class Result { public int PersonId; public List<string> Cars; } public class Program { public static void Main() { List<Person> persons = new List<Person>() { new Person { PersonId = 1, car = "Ferrari" }, new Person { PersonId = 1, car = "BMW" }, new Person { PersonId = 2, car = "Audi"} }; //With Query Syntax List<Result> results1 = ( from p in persons group p by p.PersonId into g select new Result() { PersonId = g.Key, Cars = g.Select(c => c.car).ToList() } ).ToList(); foreach (Result item in results1) { Console.WriteLine(item.PersonId); foreach(string car in item.Cars) { Console.WriteLine(car); } } Console.WriteLine("-----------"); //Method Syntax List<Result> results2 = persons .GroupBy(p => p.PersonId, (k, c) => new Result() { PersonId = k, Cars = c.Select(cs => cs.car).ToList() } ).ToList(); foreach (Result item in results2) { Console.WriteLine(item.PersonId); foreach(string car in item.Cars) { Console.WriteLine(car); } } } }

Aquí está el resultado:

1 Ferrari BMW 2 Audi ----------- 1 Ferrari BMW 2 Audi


Prueba esto :

var results= persons.GroupBy(n => n.PersonId) .Select(g => new { PersonId=g.Key, Cars=g.Select(p=>p.car).ToList())}).ToList();

Pero en cuanto al rendimiento, la siguiente práctica es mejor y más optimizada en el uso de la memoria (cuando nuestra matriz contiene muchos más elementos, como millones):

var carDic=new Dictionary<int,List<string>>(); for(int i=0;i<persons.length;i++) { var person=persons[i]; if(carDic.ContainsKey(person.PersonId)) { carDic[person.PersonId].Add(person.car); } else { carDic[person.PersonId]=new List<string>(){person.car}; } } //returns the list of cars for PersonId 1 var carList=carDic[1];


También puedes probar esto.

var results= persons.GroupBy(n => new { n.PersonId, n.car}) .Select(g => new { g.Key.PersonId, g.Key.car)}).ToList();


tratar

persons.GroupBy(x => x.PersonId).Select(x => x)

o

para comprobar si alguna persona está repitiendo en su lista intente

persons.GroupBy(x => x.PersonId).Where(x => x.Count() > 1).Any(x => x)


var results = from p in persons group p by p.PersonID into g select new { PersonID = g.Key, /**/car = g.Select(g=>g.car).FirstOrDefault()/**/}


var results = from p in persons group p by p.PersonID into g select new { PersonID = g.Key, Cars = g.Select(m => m.car) };