데이터 목록이 있을때 특정 컬럼으로 정렬을 하고나서 변경점을 찾아내는 방법을 알아봅니다.
저는 변경점을 찾아내서 그리드에서 구분선을 그을 필요가 있어 사용했습니다.
데이터가 List<dynamic> 인 경우 처리 방법입니다.
Util.cs
using System.Dynamic;
namespace ConsoleApp5
{
public static class Util
{
public static object GetPropertyValue(dynamic obj, string propertyName)
{
if (obj is ExpandoObject)
{
var dict = (IDictionary<string, object>)obj;
return dict.ContainsKey(propertyName) ? dict[propertyName] : null;
}
var prop = obj.GetType().GetProperty(propertyName);
return prop?.GetValue(obj, null);
}
}
}
Program.cs
using System.Dynamic;
namespace ConsoleApp5
{
public static class DynamicListExtensions
{
public static List<int> GetChangeIndicesByProperty(this List<dynamic> source, string propertyName)
{
// 정렬
var sorted = source.OrderBy(x => Util.GetPropertyValue(x, propertyName)).ToList();
foreach (var itemIndex in sorted.Select((item, index) => new { Item = item, Index = index }))
{
Console.WriteLine($"index {itemIndex.Index}, {itemIndex.Item.Category}");
}
// 변경 지점 찾기
return sorted
.Select((item, index) => new { Value = Util.GetPropertyValue(item, propertyName), Index = index })
.Where(x => x.Index == 0 || !object.Equals(
x.Value, Util.GetPropertyValue(sorted[x.Index - 1], propertyName)))
.Select(x => x.Index)
.ToList();
}
}
internal class Program
{
static void Main(string[] args)
{
dynamic item1 = new ExpandoObject();
item1.Category = "B";
item1.Name = "Banana";
dynamic item2 = new ExpandoObject();
item2.Category = "A";
item2.Name = "Apple";
dynamic item3 = new ExpandoObject();
item3.Category = "A";
item3.Name = "Avocado";
dynamic item4 = new ExpandoObject();
item4.Category = "C";
item4.Name = "Cherry";
dynamic item5 = new ExpandoObject();
item5.Category = "B";
item5.Name = "Blueberry";
List<dynamic> items = new List<dynamic> { item1, item2, item3, item4, item5 };
string sortBy = "Category";
var changeIndices = items.GetChangeIndicesByProperty(sortBy);
var sorted = items.OrderBy(x => Util.GetPropertyValue(x, sortBy)).ToList();
foreach (var index in changeIndices)
{
Console.WriteLine($"Change at index {index}, {sortBy}: {Util.GetPropertyValue(sorted[index], sortBy)}");
}
}
}
}
위 코드를 보면 알수 있듯이 Category 컬럼 기준으로 정렬을 한 후 해당 컬럼의 데이터가 변경되는 시점을 뽑아줍니다.
위 결과는 아래와 같습니다.
0 번째는 무조건 나와서 제거 하고 사용하면 됩니다.
아래처럼 코딩하면 한꺼번에 정렬과 변경점 index 를 한꺼번에 처리가 됩니다.
public static List<(int Index, object Value)> GetChangePoints(this List<dynamic> source, string propertyName)
{
return source
.Select(item => new { Item = item, Value = Util.GetPropertyValue(item, propertyName) })
.OrderBy(x => x.Value)
.Select((x, index) => new { x.Item, x.Value, Index = index })
.Where(x =>
x.Index > 0 && !object.Equals(
x.Value,
GetProp(source.OrderBy(y => Util.GetPropertyValue(y, propertyName)).ElementAt(x.Index - 1), propertyName)))
.Select(x => (x.Index, x.Value))
.ToList();
}
ASP.NET Core ResponseCache 활용하기 (0) | 2025.02.25 |
---|---|
CSnakes.Runtime 을 로컬 파이썬/VM 이용하기 (0) | 2025.01.25 |
CSnakes.Runtime 사용하기 (0) | 2025.01.22 |
NuGet 패키지 소스 매핑으로 패키지 설치 오류 해결하기 (0) | 2025.01.18 |
LM-Kit.NET 활용하기 (0) | 2024.10.27 |