Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

491
Vistas
linq Agrupar por y tomar los primeros y últimos registros

Estoy lidiando con un problema probablemente simple pero difícil para mí. Estoy tomando fotos de autos estacionados y las guardo con la placa del auto y la marca de tiempo. El mismo auto podría ser fotografiado varias veces durante el día.

Data de muestra

Plato Marca Modelo Insertar la fecha
99AA111 tesla S 2022-01-17 04:00:00
99AA111 tesla S 2022-01-17 04:30:00
99AA111 tesla S 2022-01-17 05:00:00
59TA3312 nissan Horizonte 2022-01-17 04:00:00
59TA3312 nissan Horizonte 2022-01-17 04:30:00
129EA512 subaru Impreza 2022-01-17 03:30:00

Lo que estoy tratando de lograr es;

Plato Marca Modelo PrimeraFotoFecha SegundaFotoFecha
99AA111 tesla S 2022-01-17 04:00:00 2022-01-17 04:30:00
99AA111 tesla S 2022-01-17 05:00:00 -
59TA3312 nissan Horizonte 2022-01-17 04:00:00 2022-01-17 04:30:00
129EA512 subaru Impreza 2022-01-17 03:30:00 -

se me ha ocurrido;

 var groupedResult = resultList.GroupBy(f => f.Plate).Select(f => new ResultListView { Plate = f.Key, FirstDate = f.Min(f => f.InsertDate), SecondDate = f.Max(f => f.InsertDate), Brand = f.FirstOrDefault().Brand, Model = f.FirstOrDefault().Model, TimeDifference = (f.Max(f => f.InsertDate) - f.Min(f => f.InsertDate)).TotalMinutes });

Pero como es obvio en el código, solo me da el primer y el último registro pero no como esperaba. Estoy tratando de agrupar por platos y si el mismo plato va más de una vez, emparejarlo con el siguiente. si solo hay una foto o tres fotos, la segunda fecha debe ser nula.

Por supuesto, se podrían aplicar diferentes lógicas, pero creo que esta es una forma más clara.

Pensé en ese bucle dentro del resultado agrupado. Tome el primero y el segundo y salte dos. Pero esto no es lo que estoy buscando.

Gracias por tu ayuda.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Bueno, teniendo (vamos a usar la tupla con nombre para la demostración):

 var resultList = new (string Plate, string Brand, string Model, DateTime InsertDate)[] { ("99AA111", "Tesla", "S", new DateTime(2022,01,17, 04,00,00)), ("99AA111", "Tesla", "S", new DateTime(2022,01,17, 04,30,00)), ("99AA111", "Tesla", "S", new DateTime(2022,01,17, 05,00,00)), ("59TA3312", "Nissan", "Skyline", new DateTime(2022,01,17, 04,00,00)), ("59TA3312", "Nissan", "Skyline", new DateTime(2022,01,17, 04,30,00)), ("129EA512", "Subaru", "Impreza", new DateTime(2022,01,17, 03,30,00)), };

Puedes GroupBy dos veces :

 var groupedResult = resultList .GroupBy(item => item.Plate) .SelectMany(group => group .OrderBy(item => item.InsertDate) .Select((item, index) => (item: item, index: index / 2)) .GroupBy(pair => pair.index) .Select(g => ( Plate: g.First().item.Plate, Brand: g.First().item.Brand, Model: g.First().item.Model, FirstPhotoDate: g.First().item.InsertDate, SecondPhotoDate: (g.Count() == 1 ? null : (DateTime?)(g.Last().item.InsertDate)) )) );

Echemos un vistazo:

 string report = string.Join(Environment.NewLine, groupedResult .Select(r => $"{r.Plate,-8} : {r.Brand,-6} : {r.Model,-7} : {r.FirstPhotoDate} : {r.SecondPhotoDate}")); Console.Write(report);

Salir:

 99AA111 : Tesla : S : 17.01.2022 4:00:00 : 17.01.2022 4:30:00 99AA111 : Tesla : S : 17.01.2022 5:00:00 : 59TA3312 : Nissan : Skyline : 17.01.2022 4:00:00 : 17.01.2022 4:30:00 129EA512 : Subaru : Impreza : 17.01.2022 3:30:00 :
over 4 years ago · Santiago Trujillo Denunciar

0

Aquí está el enfoque más limpio que se me ocurre:

 var resultList = new (string Plate, string Brand, string Model, DateTime InsertDate)[] { ("99AA111", "Tesla", "S", new DateTime(2022,01,17, 04,00,00)), ("99AA111", "Tesla", "S", new DateTime(2022,01,17, 04,30,00)), ("99AA111", "Tesla", "S", new DateTime(2022,01,17, 05,00,00)), ("59TA3312", "Nissan", "Skyline", new DateTime(2022,01,17, 04,00,00)), ("59TA3312", "Nissan", "Skyline", new DateTime(2022,01,17, 04,30,00)), ("129EA512", "Subaru", "Impreza", new DateTime(2022,01,17, 03,30,00)), }; var query = from r in resultList group (DateTime?)r.InsertDate by new { r.Plate, r.Brand, r.Model } into grs from bgrs in grs.OrderBy(x => x).Buffer(2) select new { grs.Key.Plate, grs.Key.Brand, grs.Key.Model, FirstPhotoDate = bgrs.First(), SecondPhotoDate = bgrs.Skip(1).Any() ? bgrs.Last() : null, };

Usé el operador Buffer de System.Interactive NuGet de Microsoft.

Eso me da:

consulta

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda