1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Comaparer
{
class Program
{
class Human : IComparable
{
public string Name;
public int Age;
public Human(string name, int age)
{
this.Name = name;
this.Age = age;
}
//Human에서 정의한 비교 함수.
//IComparable 인터페이스 구현.
public int CompareTo(Object obj)
{
//이름순 오름차순.
//이름이 같다면 나이순.
Human other = obj as Human;
}
}
//IComparer 인터페이스 구현을 통한 비교 함수.
class AddComparer : IComparer<Human>, IComparer<string>
{
public int Compare(Human h1, Human h2)
{
//나이순 오름차순,.
//나이가 같다면 이름순 오름차순.
return h1.Name.CompareTo(h2.Name);
return h1.Age.CompareTo(h2.Age);
}
//스트링을 숫자처럼 비교.
public int Compare(string x, string y)
{
if (x.Length.CompareTo(y.Length) == 0)
return x.CompareTo(y);
return x.Length.CompareTo(y.Length);
}
}
static void Main(string[] args)
{
//Sort예제.
// 1. int리스트를 랜덤으로 구성, Sort예제.
var intList = new List<int>();
for (int i = 0; i < 5; i++)
//intList가 오름차순으로 정렬됨.
//오름차순 정렬.
foreach (int num in intList)
Console.WriteLine(num);
// 2. string리스트를 정렬하는 예제.
var stringList = new List<string>();
for(int i = 0; i < 5; i++)
//사전순 오름차순.
Console.WriteLine("사전순 오름차순.");
foreach (string stringNum in stringList)
Console.WriteLine(stringNum);
//문자열을 int비교하듯이 Sort.
stringList.Sort(new AddComparer());
Console.WriteLine("\n숫자처럼 오름차순.");
foreach (string stringNum in stringList)
Console.WriteLine(stringNum);
//3. 사용자 정의 클래스 예제.
var HumanList = new List<Human>();
//Human의 IComparable 기준 비교.
//이름순 오름차순, 이름이 같다면 나이순 오름차순.
Console.WriteLine("IComparable 비교.");
foreach (Human h in HumanList)
Console.WriteLine("이름 : {0}, 나이 : {1}", h.Name, h.Age);
//IComaparer의 Compare기준 비교.
//나이순 오름차순. 나이가 같다면 이름순 오름차순.
Console.WriteLine("\nIComparer 비교.");
HumanList.Sort(new AddComparer());
foreach (Human h in HumanList)
Console.WriteLine("이름 : {0}, 나이 : {1}", h.Name, h.Age);
}
}
}
|
Sort를 구현하기 위해선 int CompareTo(Object obj) 함수를 이해하고 가는 것이 좋습니다.
CompareTo는 int, string, float등 기본적인 자료형에는 모두 구현되어 있습니다.
메서드를 호출하는 객체 또는 값과 매개변수로 들어오는 obj를 비교합니다.
ex) int a = 1, int b = 2 일 경우를 보겠습니다.
a.CompareTo(b)를 하면 return 값은 -1이 되겠습니다.
a 와 b의 값이 같다면 0을 return 합니다.
a 보다 b의 값이 크다면 1을 return 합니다.
값이 -1이 return 된다면 메서드를 호출하는 값과 매개변수로 들어온 obj의 자리가 바뀌지 않고 유지됩니다.
값이 0이 return 된다면 위와 마찬가지 입니다. 0의 값은 주로 다음 정렬 순서를 정의하기 위해 쓰입니다.
값이 1이 return 된다면 메서드를 호출하는 값과 매개변수 obj가 바뀌게 됩니다.
만약 arr[] = {2, 1} 라면 arr[0].CompareTo(arr[1]) 은 1이 return 되며 이는 sort시에 둘의 자리가 바뀜을 의미합니다.
* string의 경우는 다른 값과 다릅니다. 사전순으로 정렬되게 CompareTo가 구현되어 있습니다.
Sort의 정렬 방법을 정의하는 것은 이 CompareTo의 함수를 정의하는것 이라고 할 수 있습니다.
1. int정렬 예제.
랜덤으로 10이하의 수를 5번 넣었으며 그냥 Sort를 진행했습니다.
// 1. int리스트를 랜덤으로 구성, Sort예제.
var intList = new List<int>();
Random rand = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < 5; i++)
intList.Add(rand.Next(0, 10));
//intList가 오름차순으로 정렬됨.
//오름차순 정렬.
foreach (int num in intList)
Console.WriteLine(num);
내림차순으로 정렬하고 싶다면 intList.Reverse(); 를 추천드리며 굳이 정의하고 싶다면 밑으로 내리십시오;;
2. stringList 정렬 예제.
// 2. string리스트를 정렬하는 예제.
var stringList = new List<string>();
rand = new Random(DateTime.Now.Millisecond);
for(int i = 0; i < 5; i++)
stringList.Add(rand.Next().ToString());
//사전순 오름차순.
Console.WriteLine("사전순 오름차순.");
foreach (string stringNum in stringList)
Console.WriteLine(stringNum);
//문자열을 int비교하듯이 Sort.
stringList.Sort(new AddComparer());
Console.WriteLine("\n숫자처럼 오름차순.");
foreach (string stringNum in stringList)
Console.WriteLine(stringNum);
string은 기본 정렬시 사전순 오름차순 정렬된다고 설명 드렸습니다. 하지만 이와같은 방법이 마음에 들지 않을 수 있는데 그 방법을 설명드리겠습니다.
class AddComparer : IComparer<Human>, IComparer<string>
{
public int Compare(Human h1, Human h2)
{
//나이순 오름차순,.
//나이가 같다면 이름순 오름차순.
return h1.Name.CompareTo(h2.Name);
return h1.Age.CompareTo(h2.Age);
}
//스트링을 숫자처럼 비교.
public int Compare(string x, string y)
{
if (x.Length.CompareTo(y.Length) == 0)
return x.CompareTo(y);
return x.Length.CompareTo(y.Length);
}
}
2-1 Comparer의 정의
우선 클래스를 생성, IComaparer<원하는 자료형> 을 상속받고 int형의 Compare함수를 구현합니다.
사용 방법은 a.CompareTo(b)와 같이 사용하는 것을 => Compare(a, b) 이와 같이 바뀐다고 생각하시면
되겠습니다.
string을 int처럼 비교하기 위해 Compare함수를 정의했습니다. x.Length 는 int형이기 때문에
x.Length.CompareTo(y.Length)를 하시면 오름차순 정렬 되겠습니다.
우선 두 문자열의 길이를 비교합니다.
그럼 자릿수가 짧은 것은 위로 가며 같지 않다면 둘을 사전순으로 비교합니다.
아까 int 내림차순 정렬에 대해 설명드리겠습니다.
클래스에 IComparer<int>를 상속하고 Compare(int x, int y)를 정의합니다.
x.CompareTo(y)를 하면 -1이 return 되므로 바뀌지 않습니다.
y.CompareTo(x)를 하면 반대의 결과가 나오고 이는 자리가 바뀌어야 함을 의미합니다.
2-2 Comparer의 사용.
정의가 완료되면 사용해야 합니다. 아까의 클래스 객체를 하나 생성합니다.
AddComparer comp = new AddComparer();
다음 stringList.Sort(comp); 로 comp객체를 매개변수로 넘겨줍니다.
그럼 Sort시에 comp에 구현된 Compare를 기준으로 정렬이 되겠습니다.
3. 사용자 클래스
사용자 클래스의 경우 컴퓨터는 어떤 기준으로 정렬해야 할지 아예 감을잡지 못할겁니다. 여러 자료형을 묶어서
정렬해야 하는 경우라면 반드시 Compare 또는 CompareTo 를 정의해줘야 합니다.
3-1. Compare함수 정의
이 내용은 위의 string의 Compare(string x, string y)의 정의와 같습니다.
그 기준만 입맛에 맞게 해주시면 되겠습니다. 클래스에 IComparer<사용자 정의 클래스> 상속 해주시고
Compare(클래스 x, 클래스 y) 정의하면 되겠습니다. 사용법은 아까와 같습니다.
3-2 CompareTo 함수 정의.
class Human : IComparable
{
public string Name;
public int Age;
public Human(string name, int age)
{
this.Name = name;
this.Age = age;
}
//Human에서 정의한 비교 함수.
//IComparable 인터페이스 구현.
public int CompareTo(Object obj)
{
//이름순 오름차순.
//이름이 같다면 나이순.
Human other = obj as Human;
if (this.Name == other.Name)
return this.Age.CompareTo(other.Age);
return this.Name.CompareTo(other.Name);
}
}
제가 정의한 Human클래스 되겠습니다. 나이와 이름을 가지고 있어 정렬 기준이 애매합니다.
이번엔 Human 클래스에 IComparable을 상속 합니다. 다음 CompareTo(Object obj)를 정의합니다.
비교의 기준은 그 메서드를 호출하는 객체가 되고 obj는 비교할 대상이 되겠습니다. 메서드 정의는 위와 같습니다.
사용법은 HumanList.Sort()해주시면 되겠습니다.
intList의 정렬은 따로 Compare함수가 정의된 객체를 넘겨주지 않았습니다. 이는 int자체에 CompareTo가
정의되어 있으며 Sort시에 이를 자동으로 호출하기 때문입니다.
HumanList또한 마찬가지 입니다. Sort시에 IComparable의 CompareTo를 자동으로 호출해 정렬하게 됩니다.
마지막 방법으로 Collections의 클래스 사용시 OrderBy 메서드가 있습니다. 이에 대한 설명은 아래에 있습니다.
https://programming-mr.tistory.com/67
C# Select, Where, OrderBy, List.Find(All)
C# Where, Select, OrderBy, List.Find(All)를 정리해보려 합니다. 이 셋의 공통점을 정리해 보겠습니다. 1. 이 메서드들은 IEnumarable 인터페이스에서 제공하고 있습니다 (Find는 리스트). 이 말은 IEnumerable..
programming-mr.tistory.com
Excel 파일 Json으로 변환 프로젝트 (0) | 2020.04.23 |
---|---|
Excel 파일 Json으로 바꿔주는 프로그램 Ver 2.0 (0) | 2020.04.23 |
Excel파일을 json파일로 변환하는 프로그램 ver 1.0. (0) | 2020.04.22 |
C# 생성자를 여러개 정의할 경우. (0) | 2020.04.16 |
C# foreach문 (0) | 2020.04.08 |