Grupo C# por columna y forma datos jerárquicos con otras columnas
Estoy tratando de agrupar una columna y formar el resto de las columnas como niño, datos jerárquicos:
Estoy tratando de agrupar por Código y formar la relación padre e hijo de una lista plana, a continuación se encuentran los datos jerárquicos que estoy tratando de formar:
lista de fuentes:
public class ItemAssignmentFlatList
{
public int Code { get; set; }
public string Type { get; set; }
public string Description { get; set; }
public int ItemCode{ get; set; }
public DateTime EffectiveDate{ get; set; }
public string Area{ get; set; }
public string TaxCode{ get; set; }
public string LocationId { get; set; }
}
Necesidad de convertir la lista plana arriba en abajo Lista de datos jerárquicos:
public class ItemInfo
{
public int Code { get; set; }
public string Type { get; set; }
public string Description { get; set; }
public List TaxPlan { get; set; }
}
public class TaxPlan
{
public int ItemCode{ get; set; }
public DateTime EffectiveDate{ get; set; }
public string Area{ get; set; }
public string TaxCode{ get; set; }
public string LocationId { get; set; }
}
Necesidad de lista jerárquica con lista de datos plana arriba con métodos de extensión C#.
Tengo bajo código, pero buscando código limpio para reducir el número de líneas:
var items= results.GroupBy(x => new { x.Code, x.Type });
List result = new List();
foreach (var group in items)
{
var taxPlans = group.
Select(y => new TaxPlan
{
TaxArea = y.TaxArea,
ItemCode = y.ItemCode
});
var itemInfo= new ItemInfo
{
Code = group.FirstOrDefault().Code,
Type = group.FirstOrDefault().Type,
Description = group.FirstOrDefault().Description,
TaxPlan = taxPlans.ToList()
};
result.Add(itemInfo);
}
Pregunta hecha hace 3 años, 4 meses, 29 días - Por scriptsculptorbf10
4 Respuestas:
-
¿Algo como esto?
var input = new List
(){ new ItemAssignmentFlatList{ Code = 1, Area = "a" }, new ItemAssignmentFlatList{ Code = 1, Area = "b" }, new ItemAssignmentFlatList{ Code = 2, Area = "c" } }; input .GroupBy( x => x.Code, (int code, IEnumerable items) => { var first = items.FirstOrDefault(); var key = new ItemInfo { Code = first.Code //, ... }; var plan = items. Select(y => new TaxPlan { Area = y.Area //, ... }); return new { key = key, items = plan }; } ).Dump(); Respondida el Dec 18, 2020 a las 21:25 - por cybermage
Votos positivos: 0 | Votos negativos: 0 -
Cada vez que tienes una secuencia de objeto similar, y quieres hacer "Items con sus SubItems", basado en propiedades comunes en tu secuencia de origen, considera usar una de las sobrecargas de Enumerable. GroupBy
Debido a que no sólo quiere "Grupos de elementos fuente" pero desea especificar su salida, considere utilizar la sobrecarga que tiene un resultado del parámetroSelector.
- parámetro keySelector: qué deben tener todos los elementos de un grupo en común
- Resultado del parámetroSelector: use la cosa común, y todos los elementos que tienen esta cosa común para hacer un elemento de salida.
.
IEnumerable
flatItemAssignments = ... IEnumerable items = flatItemAssignments // make groups with same {Code, Type, Description} .GroupBy(flatItemAssignment => new {Code, Type, Description}, // parameter resultSelector: take the common CodeTypeDescription, // and all flatItemAssignments that have this common value // to make one new ItemInfo (codeTypeDescription, flatItemAssignmentsWithThisCodeTypeDescription) => new ItemInfo { Code = codeTypeDescription.Code, Type = codeTypeDescription.Type, Description = codeTypeDescription.Description, TaxPlans = flatItemAssignmentsWithThisCodeTypeDescription .Select(flatItemAssignment => new TaxPlan { ItemCode = flatItemAssignment.ItemCode, EffectiveDate = flatItemAssignment.EffectiveDate, Area = flatItemAssignment.Area, ... }) .ToList(), }); Respondida el Dec 18, 2020 a las 21:30 - por scriptsphinx
Votos positivos: 0 | Votos negativos: 0 -
Para simplificar tu código y reducir el número de líneas, puedes utilizar expresiones lambda y métodos de extensión de LINQ. Aquí te muestro una manera de hacerlo:
csharp var results = // Tu lista de datos plana var result = results .GroupBy(x => new { x.Code, x.Type }) .Select(group => new ItemInfo { Code = group.Key.Code, Type = group.Key.Type, Description = group.First().Description, TaxPlan = group.Select(y => new TaxPlan { ItemCode = y.ItemCode, EffectiveDate = y.EffectiveDate, Area = y.Area, TaxCode = y.TaxCode, LocationId = y.LocationId }).ToList() }) .ToList();
En este código, utilizamos
GroupBy
para agrupar porCode
yType
, luego conSelect
creamos un nuevoItemInfo
con las propiedades correspondientes. ParaTaxPlan
, usamos otra proyecciónSelect
dentro de la lambdaSelect
principal.Con este enfoque, puedes simplificar tu código y hacerlo más legible.
Respondida el Dec 19, 2020 a las 21:29 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Versión mejorada y optimizada:
csharp using System.Collections.Generic; using System.Linq; public static class ItemAssignmentExtensions { public static IEnumerable
ToHierarchicalData(this IEnumerable flatList) { return flatList .GroupBy(x => new { x.Code, x.Type }) .Select(g => new ItemInfo { Code = g.Key.Code, Type = g.Key.Type, Description = g.FirstOrDefault()?.Description, TaxPlan = g.Select(x => new TaxPlan { ItemCode = x.ItemCode, EffectiveDate = x.EffectiveDate, Area = x.Area, TaxCode = x.TaxCode, LocationId = x.LocationId }).ToList() }); } } Uso:
csharp // Lista de datos planos de ItemAssignment var flatList = new List
{ // Datos de muestra... }; // Conversión a datos jerárquicos de ItemInfo var hierarchicalData = flatList.ToHierarchicalData(); Explicación:
El método de extensión
ToHierarchicalData
toma una secuencia de objetosItemAssignmentFlatList
y la convierte en una secuencia de objetosItemInfo
jerárquicos. Utiliza la agrupación LINQ para agrupar los elementos planos porCode
yType
. Para cada grupo, crea un objetoItemInfo
con elCode
,Type
yDescription
del primer elemento. También crea una lista de objetosTaxPlan
a partir de los elementos del grupo, utilizando la proyección de propiedades. * El resultado es una secuencia de objetosItemInfo
jerárquicos, con una lista de objetosTaxPlan
anidados para cada elemento.Respondida el Dec 19, 2020 a las 21:38 - por Gemini
Votos positivos: 0 | Votos negativos: 0