foreach
- 배열과 함께 사용되는 반복문
- 한번 반복을 수행할 때 마다 배열/컬렉션 요소를( scores 의) 차례대로 순회하며 in앞의 변수 score에 담는다
foreach (int score int scores)
{
Console.WrieLine(score);
}
마지막 요소에 접근하고 싶을 때
원래는 배열의 길이 =5, 마지막 요소 = 4이기 때문에 scores[scores.Length-1]
(5-1 = 4) => scores[4] 를 해줬는데
C# 8.0부터는 이런 불편을 없앤 System.Index형식과 ^연산자가 생김
^연산자 : 컬렉션의 마지막부터 역순으로 인덱스를 지정하는 기능
^1 : 컬렉션의 마지막 요소 (score.Length - 1 이라고 생각)
^2 : 마지막에서 두번째
^3 : 마지막에서 세번쨰
^를 Length와 같다고 생각하면 쉬움. 익숙해지기 전까지 ^0 = score.Length-0이라고 생각
^연산자의 결과는 System.Index 형식의 인스턴스로 저장됨
System.Index last = ^1;
scores[last] = 34;
한 줄로 요약하면
scores[^1] = 34;
배열을 초기화하는 방법 세가지
① 배열의 용량을 명시
string[] array1 = new string[3] {"안녕, "Hello", "Halo"}'
② 배열의 용량을 생략
string[] array2 = new string[] {"안녕", "Hello", "Halo"};
③ new연산자, 형식과 대괄호, 배열의 용량 모두 생략
string[] array3 = {"안녕", "Hello", "Halo"};
3번이 젤 편하고 많이 쓰지만, 가독성이 좋고 원소가 없는 빈 배열을 만들어줄땐 1번이 좋음
System. Array
// 해당조건을 만족하는 번호 반환, 없으면 -1
System.Array.FindIndex(배열, x => x.name == "A");
// 해당조건을 만족하는 첫번째 값 반환
System.Array.Find(배열, x => x.name == "A");
// 해당조건을 만족하는 모든 값 리스트로 반환
System.Array.FindAll(배열, x => x.name == "A");
// 중복만 추출
var redundantArray = System.Array.FindAll(배열, x => List.Contains(x));
// RemoveAll 용도
System.Array.FindAll(배열, x => x.name != "A");
// 해당조건을 만족하는 요소가 한 개라도 존재하는지 검사
System.Array.Exists(배열, x => x.name = "A");
// 내용물에 전부 1 더해 반환
int[] 배열 = System.Array.ConvertAll(배열, x => x+1);
// 0으로 초기화
int[] 배열 = System.Array.ConvertAll(배열, x => 0);
// true 검사
System.Array.Find(배열, x => x == true);
// true 검사2
System.Array.TrueForAll(배열, x => x.isOn == false);
// 포함 여부 검사
if (System.Array.TrueForAll(배열, x => List.Contains(x));
사용 예시)
백준 - 1차원 배열 (+ System.Array, + System.Array.ConvertAll)
https://www.acmicpc.net/problem/10807 10807번: 개수 세기 첫째 줄에 정수의 개수 N(1 ≤ N ≤ 100)이 주어진다. 둘째 줄에는 정수가 공백으로 구분되어져있다. 셋째 줄에는 찾으려고 하는 정수 v가 주어진다.
zizh.tistory.com
static void Main(string[] args)
{
// 정수의 개수
int n = int.Parse(Console.ReadLine());
// 정수 배열
string [] numbers = Console.ReadLine().Split();
// 찾으려는 정수
string v = Console.ReadLine();
//위의 foreach문이 Array.FindAll로 한줄로 정리됨
// 찾기
int result = Array.FindAll(numbers, x => x == v).Length;
Console.WriteLine(result);
}
배열 분할하기
Array.Copy()메소드도 좋지만 배열 분할 방법을 알게 되면 Array.Copy()메소드를 아마도 사용하지 않게 된다
새로운 배열 분할 방법을 알려면 C# 8.0에서 System.Index형식과 함께 도입된 System.Range를 알 필요가 있다
System.Range
- 시작 인덱스와 마지막 인덱스를 이용해서 범위를 나타낸다
- System.Range 객체를 생성할 때는 다음과 같이 .. 연산자를 이용
scores배열을 r1(0..3)인덱스 범위에 따라 분할하고 int[] sliced 배열에 복사
System.Range r1 = 0..3;
int[] sliced = scores[r1];
int[] sliced = scores[0..3]; //더 간결하게
주의할점은 0..3이라고 하면 0포함, 3은 제외 = 0~2까지
int[] sliced3 = scores[..3]; // 0~2
int[] sliced4 = scores[1..]; // 1~마지막요소
int[] sliced5 = scores[..]; //전체
System.Range객체를 생성할 때 System.Index객체를 이용할 수도 있음
System.Index idx = ^1;
int[] sliced5 = scores[..idx];
int[] sliced6 = scores[..^1]; //더 간결
2차원 배열
2차원 배열을 선언하는 방법
각 차원의 용량 또는 길이를 , 로 구분해서 [와 ] 사이에 입력해준다
데이터형식[,] 배열이름 = new 데이터형식[2차원 길이, 1차원 길이];
2차원 배열을 코드에서 읽을 때는 [] 안에 있는 차원의 길이를 뒤에서부터 읽으면 이해하기 쉽다
예를 들면 int[2, 3]은 길이는 3인 1차원 배열을 원소로 2개 갖고 있는 2차원 배열
2차원 배열의 원소에 접근
Console.WriteLine(array[0, 2]);
2차원 배열 선언과 동시에 초기화하는 방법 세가지
int[,] arr = new int[2,3] {{1,2,3}, {4,5,6}};
int[,] arr = new int {{1,2,3}, {4,5,6}};
int[,] arr = {{1,2,3}, {4,5,6}};
예제
GetLength 사용
//WriteLine(arr.Length); => 6출력 (2x3)
//WriteLine(arr.GetLength(0)); => 2출력 (2차원 길이)
//WriteLine(arr.GetLength(1)); => 3출력 (1차원 길이)
static void Main(string[] args)
{
int[,] arr = new int[2, 3] { { 1, 2, 3 }, { 4, 5, 6 } };
//WriteLine(arr.Length); => 6출력 (2x3)
//WriteLine(arr.GetLength(0)); => 2출력 (2차원 길이)
//WriteLine(arr.GetLength(1)); => 3출력 (1차원 길이)
for (int i = 0; i < arr.GetLength(0); i++)
{
for(int j = 0; j< arr.GetLength(1); j++)
{
Write($"[{i},{j}] : {arr[i,j]} ");
}
WriteLine();
}
}
출력
[0,0] : 1 [0,1] : 2 [0,2] : 3
[1,0] : 4 [1,1] : 5 [1,2] : 6
다차원 배열 int[, ,] arr = new int[4, 3, 2] .... 생략
가변 배열 [] []
- 영어로 Jagged(들쭉 날쭉한) Array
- 요소로 배열을 갖는다
- 다음과 같이 선언
데이터형식 [][] 배열이름 = new 데이터형식 [가변 배열의 용량][];
선언 예시 : 용량이 3개인 배열 jagged를 선언한 다음, jagged의 각 요소에 크기가 다른 배열들을 할당
0번 요소에는 길이가 5인 배열, 1번 요소에는 길이가 3인 배열
int[][] jagged = new int [3][];
jagged[0] = new int[5] { 1,2,3,4,5 };
jagged[1] = new int[] { 10,20,30 };
jagged[2] = new int[] { 100, 200 };
선언과 동시에 초기화도 물론 가능
int[][] jaggged = new int[2][] }
new int[] { 1000,2000 },
new int[4] { 6,7,8,9 } };