유료 매크로 프로그램 다운로드
http://ngmsoftware.com/bbs/board.php?bo_table=product_review
#매크로 #메크로 #매크로프로그램 #엔지엠소프트웨어 #엔지엠에디터 #엔지엠플레이어 #비활성매크로 #하드웨어매크로 #기계식매크로 #마우스광클릭 #키보드매크로 #이미지서치 #이미지매치 #블로그 #카페 #인스타그램 #유튜브 #소셜네트워크 #카카오톡 #텔레그램 #자동화
- 엔지엠 커뮤니티 월 이용료: 4,500원, 1년 이용료: 55,000원 (전체 기능의 80프로)
- 엔지엠 얼티밋 월 이용료: 6,500원, 1년 이용료: 77,000원 (전체 기능의 90프로)
- 엔지엠 엔터프라이즈 월 이용료: 9,200원, 1년 이용료: 110,000원 (전체 기능 사용)
안녕하세요. 엔지엠소프트웨어입니다. 오늘은 배열 정렬 기능을 개발 해볼께요. 앞서, 배열을 처리하는 방법을 배웠기 때문에 자잘한 로직 설명은 건너뛰고 정렬 기능에 대해서만 설명하면서 코딩하면 될듯합니다. 우선, 배열 정렬 액션을 하나 추가 해줍니다. 모델명은 ArraySortModel입니다. 이름만 봐도 아~ 이녀석이 뭘 하는구나하고 유추할 수 있습니다. 괜찮은 이름이죠?
배열을 정렬하기 위해서는 아래와 같은 속성들이 필요합니다. 중요한 몇가지만 알고 넘어가면 될거 같아요.
public class ArraySortModel : BaseModel
{
[NonSerialized]
private string[]? _datas;
[LocalizedCategory("Data")]
[LocalizedDisplayName("Result")]
[LocalizedDescription("Result")]
[Browsable(true)]
[DefaultValue(null)]
public string[]? Result { get; set; }
[LocalizedCategory("Array")]
[LocalizedDisplayName("RepeatData")]
[LocalizedDescription("RepeatData")]
[Browsable(true)]
[DefaultValue(null)]
public string[]? ArrayData { get { return _datas; } set { _datas = value; } }
[LocalizedCategory("Array")]
[LocalizedDisplayName("ArraySortOption")]
[LocalizedDescription("ArraySortOption")]
[Browsable(true)]
[DefaultValue(typeof(Ai.Definition.Sort), "None")]
public Ai.Definition.Sort ArraySortOption { get; set; } = Definition.Sort.None;
[LocalizedCategory("Array")]
[LocalizedDisplayName("DataType")]
[LocalizedDescription("DataType")]
[Browsable(true)]
[DefaultValue(typeof(Ai.Definition.DataType), "Text")]
public Ai.Definition.DataType DataType { get; set; } = Definition.DataType.Text;
[LocalizedCategory("Array")]
[LocalizedDisplayName("SortOption")]
[LocalizedDescription("SortOption")]
[Browsable(true)]
[DefaultValue(typeof(Ai.Definition.DataType), "X")]
public Ai.Definition.SortOption SortOption { get; set; } = Definition.SortOption.X;
ArraySortOption은 기본값이 None입니다. 아무것도 처리하지 않는데요. 어떻게 배열의 값을 처리할지는 사용자가 선택해야 합니다.
[LocalizedCategory("Array")]
[LocalizedDisplayName("ArraySortOption")]
[LocalizedDescription("ArraySortOption")]
[Browsable(true)]
[DefaultValue(typeof(Ai.Definition.Sort), "None")]
public Ai.Definition.Sort ArraySortOption { get; set; } = Definition.Sort.None;
정렬 기준은 아래와 같습니다. 오름차순, 내림차순, 역순, 특정 위치에서 가까운 순서와 먼 순서 그리고, 셔플입니다.
public enum Sort
{
None = 0,
Ascending = 1,
Descending = 2,
Reverse = 3,
Far = 4,
Near = 5,
Shuffle = 6
}
Far와 Near는 데이터 형식이 좌표를 포함하고 있을 때 사용하는 옵션인데요. 특정 숫자나 문자에도 적용할 수 있을듯 합니다. 이 부분은 나중에 추가 개발을 통해서 자세하게 알아볼께요. 배열 정렬하기 2부 내용도 기대해주시고, 오늘은 오름차순과 내림차순, 역순을 개발할거예요.
데이터 형식은 아래와 같은데요. 테이터 형식에 따라서 처리 로직이 달라져야 합니다. 전부다 문자로 변환해서 처리해도 되긴 하지만, 이렇게하면 의도하지 않은 방식으로 정렬될 수 있습니다. 가령, 좌표의 경우 나는 Y좌표를 기준으로 위에서 아래로 정렬하고 싶은데 X 값이 가장 앞에 있어서 X 순서로 정렬되는 경우를 생각 해볼 수 있을거 같아요.
public enum DataType
{
Text = 0,
Number = 1,
Point = 2,
Size = 3,
Rectangle = 4
}
위 내용에 연장선으로 데이터가 좌표, 크기, 사각형인 경우 아래와 같이 추가 옵션을 제공해야 합니다.
[LocalizedCategory("Array")]
[LocalizedDisplayName("SortOption")]
[LocalizedDescription("SortOption")]
[Browsable(true)]
[DefaultValue(typeof(Ai.Definition.DataType), "X")]
public Ai.Definition.SortOption SortOption { get; set; } = Definition.SortOption.X;
SortOption은 아래와 같이 많은 속성들이 있습니다. 좌표가 사용하는 것과 크기가 사용하는게 나눠져 있습니다. 사각형은 둘다 가지고 있으므로 모두 사용해야 합니다. 참고로, XY와 XnY가 있는데요. 이 둘의 차이점은 정렬 방법입니다. 정렬을 내림차순으로 선택했을 때 XY는 X 기준으로 내림차순하고, 그 다음에 Y도 내림차순으로 정렬해줍니다. X 좌표 값이 같을수도 있으니까요. 이런 경우 Y 좌표 설정 값으로 한번 더 정렬합니다. XnY는 X 좌표로 우선 정렬하고, 같은 값인 경우에는 Y 좌표는 오름차순으로 정렬할 때 사용하는 옵션입니다.
public enum SortOption
{
X = 0,
Y = 1,
XY = 2,
XnY = 3,
YX = 4,
YnX = 5,
W = 6,
H = 7,
WH = 8,
WnH = 9,
HW = 10,
HnW = 11
}
데이터 형식에 따라서 switch ~ case로 하나씩 구현해줘야 합니다.
switch (DataType)
{
case Definition.DataType.Text:
var arrText = ArrayData.Cast<object>().Select(x => x.ToString()).ToArray();
switch (ArraySortOption)
{
case Definition.Sort.Ascending:
Result = arrText.OrderByNatural(o => o).ToArray();
break;
case Definition.Sort.Descending:
Result = arrText.OrderByDescendingNatural(o => o).ToArray();
break;
case Definition.Sort.Reverse:
Result = arrText.Reverse().ToArray();
break;
case Definition.Sort.Shuffle:
Result = arrText.Shuffle().ToArray();
break;
case Definition.Sort.Far:
break;
case Definition.Sort.Near:
break;
}
여기서 핵심 내용이 하나 나옵니다. 우리가 일반적으로 정려할 때 아래 내용을 고려해봐야 합니다. { "a10", "a7", "a" } 배열이 있으면 어떻게 정렬이 될까요? 아마도 예상으로는 a, a7, a10처럼 될거라고 생각할거 같은데요. 실제로는 문자열이기 때문에 a, a10, a7과 같이 정렬됩니다. 이렇게 되는 이유는 문자를 앞에서부터 하나씩 비교하면서 정렬하기 때문입니다. 그래서, a 다음에 1이 나오는 a10이 a7보다 우선됩니다. OrderBy가 아닌 Sort를 사용해도 결과는 동일합니다.
하지만, 윈도우에서 정렬은 어떨까요? a, a7, a10과 같이 정렬되는데요. 이게 자연스럽죠?
그래서, 프로그래밍에서 윈도우처럼 자연스럽게 정렬하기 위한 다양한 방법들이 존재합니다. 윈도우의 정렬 기능을 빼와서 적용시킬수도 있는데요. 이건, 윈도우 환경이 아닌 리눅스나 유닉스와 같은 곳에서는 어차피 사용하지 못하고, 로직을 만들어야 합니다. 그래서, 보통 아래와 같이 사용합니다.
public static IEnumerable<T> OrderByNatural<T>(IEnumerable<T> items, Func<T, object> selector, StringComparer? stringComparer = null)
{
var regex = new Regex(@"\d+", RegexOptions.Compiled);
int maxDigits = items
.SelectMany(i => regex.Matches(selector(i).ToString()).Cast<Match>().Select(digitChunk => (int?)digitChunk.Value.Length))
.Max() ?? 0;
return items.OrderBy(i => regex.Replace(selector(i).ToString(), match => match.Value.PadLeft(maxDigits, '0')), stringComparer ?? StringComparer.CurrentCulture);
}
이제 만들어진 정렬 기능을 사용해서 테스트를 해볼께요. 몇가지 복합적으로 사용해야 합니다. 테스트 내용은 아래 동영상을 참고하세요.
[ 각종 자동화 매크로 및 RPA 프로그램 제작 해드립니다. ]
[ 초보자도 쉽게 따라할 수 있는 기초 학습 강좌 보기 ]
원본 글 보기
http://ngmsoftware.com/bbs/board.php?bo_table=tip_and_tech
댓글