728x90
반응형
728x170
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
#region 객체 컬렉션 특정 객체 속성 값의 집합 구하기 - GetDistinctCollection(sourceCollection, propertyNameArray)
/// <summary>
/// 객체 컬렉션 특정 객체 속성 값의 집합 구하기
/// </summary>
/// <param name="sourceCollection">소스 컬렉션</param>
/// <param name="propertyNameArray">속성명 배열</param>
/// <returns>객체 컬렉션 특정 객체 속성 값의 집합</returns>
public ObservableCollection<object> GetDistinctCollection(ObservableCollection<object> sourceCollection, string[] propertyNameArray)
{
if(sourceCollection == null || sourceCollection.Count == 0)
{
return null;
}
var result = sourceCollection.AsEnumerable().GroupBy(item => new DistinctTuple<object>(from propertyName in propertyNameArray select item.GetType().GetProperty(propertyName).GetValue(item)));
int propertyNameCount = propertyNameArray.Length;
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(sourceCollection[0]);
DynamicClass dynamicClass = new DynamicClass(); // '동적 클래스 사용하기' 참조
for(int i = 0; i < propertyNameCount; i++)
{
dynamicClass.AddProperty(propertyNameArray[i], pdc[propertyNameArray[i]].PropertyType);
}
dynamicClass.CreateType();
ObservableCollection<object> targetCollection = new ObservableCollection<object>();
foreach(var group in result)
{
dynamicClass.CreateInstance();
for(int i = 0; i < propertyNameCount; i++)
{
dynamicClass.SetValue(i, group.Key.ValueArray[i]);
}
targetCollection.Add(dynamicClass.Instance);
}
return targetCollection;
}
#endregion
/// <summary>
/// 중복 제거 튜플
/// </summary>
/// <typeparam name="T">타입</typeparam>
public class DistinctTuple<T> : IEquatable<DistinctTuple<T>>
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 값 배열
/// </summary>
public readonly T[] ValueArray;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - DistinctTuple(enumerable)
/// <summary>
/// 생성자
/// </summary>
/// <param name="enumerable">열거 가능형</param>
public DistinctTuple(IEnumerable<T> enumerable)
{
ValueArray = enumerable.ToArray();
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 동등 여부 조사하기 - Equals(sourceTuple)
/// <summary>
/// 동등 여부 조사하기
/// </summary>
/// <param name="sourceTuple">소스 Tuple</param>
/// <returns>동등 여부</returns>
public bool Equals(DistinctTuple<T> sourceTuple)
{
if(ReferenceEquals(this, sourceTuple))
{
return true;
}
if(sourceTuple == null)
{
return false;
}
int length = ValueArray.Length;
if(length != sourceTuple.ValueArray.Length)
{
return false;
}
for(int i = 0; i < length; i++)
{
if(!Equals(ValueArray[i], sourceTuple.ValueArray[i]))
{
return false;
}
}
return true;
}
#endregion
#region 동등 여부 조사하기 - Equals(sourceObject)
/// <summary>
/// 동등 여부 조사하기
/// </summary>
/// <param name="sourceObject">소스 객체</param>
/// <returns>동등 여부</returns>
public override bool Equals(object sourceObject)
{
if(ReferenceEquals(this, sourceObject))
{
return false;
}
if(sourceObject == null)
{
return false;
}
return Equals(sourceObject as DistinctTuple<T>);
}
#endregion
#region 해시 코드 구하기 - GetHashCode()
/// <summary>
/// 해시 코드 구하기
/// </summary>
/// <returns>해시 코드</returns>
public override int GetHashCode()
{
int hashCode = 17;
foreach(var value in ValueArray)
{
hashCode = hashCode * 37 + (!ReferenceEquals(value, null) ? value.GetHashCode() : 0);
}
return hashCode;
}
#endregion
}
728x90
반응형
그리드형(광고전용)
'C# > Common' 카테고리의 다른 글
[C#/COMMON] ExpandoObject 클래스 : 속성 추가하기 (0) | 2016.01.20 |
---|---|
[C#/COMMON] 경로 추가하기 (0) | 2016.01.03 |
[C#/COMMON] 객체 컬렉션 특정 속성 값에 따라 정렬하기 (속성 2개 이상 지정 가능) (0) | 2016.01.02 |
[C#/COMMON] 객체 리스트 특정 속성 값에 따라 정렬하기 (속성 2개 이상 지정) (0) | 2016.01.02 |
[C#/COMMON] 객체 리스트 특정 속성 값에 따라 정렬하기 (속성 1개만 지정) (0) | 2016.01.02 |
[C#/COMMON] 객체 리스트 특정 객체 속성 값의 집합 구하기 (속성 2개 이상 지정 가능) (0) | 2016.01.02 |
[C#/COMMON] Nullable 타입 여부 구하기 (0) | 2016.01.01 |
[C#/COMMON] 객체 컬렉션 특정 객체 속성 값의 집합 구하기 (속성 1개만 지정) (0) | 2015.12.19 |
[C#/COMMON] Null Coalescing 연산자 사용하기 (0) | 2015.12.16 |
[C#/COMMON] 정규 분포 정렬 리스트 구하기 (0) | 2015.12.15 |
댓글을 달아 주세요