-
[프렉티컬 C#] 배열과 List<T>Development/C# 2023. 7. 26. 15:15728x90
여러 요소를 한꺼번에 관리할 수 있게 해주는 데이터 구조는 배열과 컬렉션이 있다.
컬렉션
- Group of objects
- Collections provide a more flexible way to work with groups of objects. Unlike arrays, the group of objects you work with can grow and shrink dynamically as the needs of the application change.
Collections (C#)
Learn about collections in C#, which are used to work with groups of objects. Collections can grow and shrink dynamically as the needs of the application change.
learn.microsoft.com
컬렉션 종류
Dictionary<TKey,TValue> 키에 따라 구성된 키/값 쌍의 컬렉션을 나타냅니다. List<T> 인덱스로 액세스할 수 있는 개체 목록을 나타냅니다. 목록의 검색, 정렬 및 수정에 사용할 수 있는 메서드를 제공합니다. Queue<T> FIFO(선입선출) 방식의 개체 컬렉션을 나타냅니다. SortedList<TKey,TValue> 연관된 IComparer<T> 구현을 기반으로 키에 따라 정렬된 키/값 쌍의 컬렉션을 나타냅니다. Stack<T> LIFO(후입선출) 방식의 개체 컬렉션을 나타냅니다. 차이점
배열
인스턴스를 생성할 때 저장할 수 있는 요소의 개수가 정해지고 나중에 수정 불가
컬렉션
인스턴스 생성 후 요소 추가, 삽입, 삭제 가능
공통점
둘 다 IEnumerable<T> 인터페이스를 가지고 있다.
Enumerable.Repeat 메서드
동일한 값이 반복되는 시퀀스를 생성한다.
* 연속된 IEnumerable<T>형 데이터를 시퀀스라고 한다.
Enumerable.Repeat<TResult>(TResult, Int32) 메서드 (System.Linq)
반복되는 단일 값이 들어 있는 시퀀스를 생성합니다.
learn.microsoft.com
var strings = Enumerable.Repeat(-1, 20) // -1을 20번 생성하라는 의미 .ToList(); // List<int>로 변환 var strings = Enumerable.Repeat("hi", 10) // "hi"를 10번 생성하라는 의미 .ToArray();
Enumerable.Range 메서드
1, 2, 3, ... 10 과 같이 연속되는 숫자값을 설정할 수 있다.
Enumerable.Range(Int32, Int32) 메서드 (System.Linq)
지정된 범위 내의 정수 시퀀스를 생성합니다.
learn.microsoft.com
var array = Enumerable.Range(1, 20) // 두 번째 인수에는 생성할 개수를 지정 .ToArray();
Queryable.Average 메서드
숫자 값 시퀀스의 평균을 계산합니다.
Queryable.Average 메서드 (System.Linq)
숫자 값 시퀀스의 평균을 계산합니다.
learn.microsoft.com
Queryable.Sum 메서드
숫자 값 시퀀스의 합을 계산합니다.
Queryable.Sum 메서드 (System.Linq)
숫자 값 시퀀스의 합을 계산합니다.
learn.microsoft.com
Queryable.Min 메서드
최솟값을 구한다.
Queryable.Min 메서드 (System.Linq)
제네릭 IQueryable<T>의 각 요소에 대해 프로젝션 함수를 호출하고 최소 결과 값을 반환합니다.
learn.microsoft.com
Queryable.Max 메서드
최댓값을 구한다.
Queryable.Max 메서드 (System.Linq)
제네릭 IQueryable<T>의 각 요소에 대해 프로젝션 함수를 호출하고 최대 결과 값을 반환합니다.
learn.microsoft.com
Queryable.Count 메서드
시퀀스의 요소 수를 반환합니다.
Queryable.Count 메서드 (System.Linq)
시퀀스의 요소 수를 반환합니다.
learn.microsoft.com
Queryable.Any 메서드
- 조건에 일치하는 요소가 시퀀스에 존재하는지 여부를 조사한다.
- 조건에 일치하는 요소가 하나라도 발견되면 true 반환, 발견되지 않으면 false 반환
Queryable.Any 메서드 (System.Linq)
IQueryable<T> 시퀀스에 요소가 하나라도 있는지 또는 특정 조건에 맞는 요소가 있는지 확인합니다.
learn.microsoft.com
Queryable.All 메서드
- 시퀀스의 모든 요소가 특정 조건에 맞는지 확인한다.
- 시퀀스가 비어 있으면 항상 true 반환한다.
Queryable.All<TSource> 메서드 (System.Linq)
시퀀스의 모든 요소가 특정 조건에 맞는지 확인합니다.
learn.microsoft.com
Queryable.SequenceEqual 메서드
두 시퀀스가 서로 같은지 확인합니다.
Queryable.SequenceEqual 메서드 (System.Linq)
두 시퀀스가 서로 같은지 확인합니다.
learn.microsoft.com
var num1 = new List<int> {1, 2, 3, 4, 5}; var num2 = new List<int> {1, 2, 3, 4, 5}; bool equal = num1.SequenceEqual(num2);
Queryable.FirstOrDefault 메서드
- 시퀀스의 첫 번째 요소를 반환하거나, 요소가 없으면 기본값을 반환한다.
- First 메서드는 조건을 만족하는 요소가 발견되지 않으면 InvaildOperation Exception 에외가 발생하지만,
FirstOrDefault 메서드는 default(T)의 값을 반환한다.
- 마지막 요소를 구하려면 Last 메서드나 LastDefault 메서드 사용
*수치형의 default(T)는 0이고 구조체의 default(T)는 각 멤버의 값이 해당 형에 따라 0이나 null이다. 참조형은 null
Queryable.FirstOrDefault 메서드 (System.Linq)
시퀀스의 첫 번째 요소를 반환하거나, 요소가 없으면 기본값을 반환합니다.
learn.microsoft.com
FindIndex 메서드
- 지정한 조건자에 정의된 조건과 일치하는 요소를 검색하여 일치하는 요소 중 첫 번째 요소의 인덱스(0부터 시작)를 반환한다.
- 조건이 일치하는 마지막 인덱스를 구할 때는 FindLastIndex 메서드 사용한다.
- FindIndex와 FindLastIndex 메서드는 배열과 List<T>에서만 사용할 수 있다.
Array.FindIndex 메서드 (System)
지정한 조건자에 정의된 조건과 일치하는 요소를 검색하여 Array 또는 그 일부에서 일치하는 요소 중 첫 번째 요소의 인덱스(0부터 시작)를 반환합니다.
learn.microsoft.com
List<T>.FindIndex 메서드 (System.Collections.Generic)
지정된 조건자에 정의된 조건과 일치하는 요소를 검색하고 List<T>이나 그 일부에서 처음으로 검색한 요소의 인덱스(0부터 시작)를 반환합니다. 이 메서드는 조건이 일치하는 항목이 없는 경우 -1
learn.microsoft.com
Queryable.Where 메서드
조건자에 따라 값의 시퀀스를 필터링합니다.
Queryable.Where 메서드 (System.Linq)
조건자에 따라 값의 시퀀스를 필터링합니다.
learn.microsoft.com
Queryable.Take 메서드
- 시퀀스 시작 위치에서 지정된 수의 연속 요소를 반환한다.
- 지정한 개수만큼 없어도 오류를 발생시키지 않고 구할 수 있는 만큼의 요소를 구한다.
Queryable.Take 메서드 (System.Linq)
시퀀스 시작 위치에서 지정된 수의 연속 요소를 반환합니다.
learn.microsoft.com
int[] grades = { 59, 82, 70, 56, 92, 98, 85 }; // Sort the grades in descending order and take the first three. IEnumerable<int> topThreeGrades = grades.AsQueryable().OrderByDescending(grade => grade).Take(3); Console.WriteLine("The top three grades are:"); foreach (int grade in topThreeGrades) Console.WriteLine(grade); /* This code produces the following output: The top three grades are: 98 92 85 */
Queryable.TakeWhile 메서드
- 지정된 조건이 만족하는 동안에만 시퀀스의 요소를 반환한다.
- 조건을 만족하지 않는 요소가 발견된 시점에서 열거가 종료된다.
Queryable.TakeWhile 메서드 (System.Linq)
지정된 조건이 true인 동안 시퀀스의 요소를 반환하고 나머지 요소를 건너뜁니다.
learn.microsoft.com
Queryable.SkipWhile 메서드
- TakeWhile 메서드와 반대
- 지정된 조건을 만족하는 동안에는 요소를 건너뛰고 나머지 요소를 반환합니다.
- 조건을 만족하지 않는 요소가 발견된 시점에서 열거가 종료된다.
Queryable.SkipWhile 메서드 (System.Linq)
지정된 조건이 true이면 시퀀스에 있는 요소를 무시하고 나머지 요소를 반환합니다.
learn.microsoft.com
Queryable.Select 메서드
시퀀스의 각 요소를 새 폼에 투영합니다.
Queryable.Select 메서드 (System.Linq)
시퀀스의 각 요소를 새 폼에 투영합니다.
learn.microsoft.com
Queryable.Distinct 메서드
중복된 요소를 제거한다.
Queryable.Distinct 메서드 (System.Linq)
시퀀스의 고유 요소를 반환합니다.
learn.microsoft.com
Queryable.OrderBy 메서드
시퀀스의 요소를 오름차순으로 정렬합니다.
Queryable.OrderBy 메서드 (System.Linq)
시퀀스의 요소를 오름차순으로 정렬합니다.
learn.microsoft.com
Queryable.OrderByDescending 메서드
시퀀스의 요소를 내림차순으로 정렬합니다.
Queryable.OrderByDescending 메서드 (System.Linq)
시퀀스의 요소를 내림차순으로 정렬합니다.
learn.microsoft.com
Queryable.Concat 메서드
두 시퀀스를 연결합니다.
Queryable.Concat<TSource>(IQueryable<TSource>, IEnumerable<TSource>) 메서드 (System.Linq)
두 시퀀스를 연결합니다.
learn.microsoft.com
✓ foreach나 for 루프 안에서 리스트에 있는 요소를 삭제하면 안 된다.
// InvalidOperation Exception 예외 발생 List<int> list = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; foreach (int n in list) { if (n % 4 == 0) list.Remove(n); }
연습문제
문제 6.1
var numbers = new int[] { 5, 10, 17, 9, 3, 21, 10, 40, 21, 3, 35 }; // 1 var max = numbers.Max(); Console.WriteLine(max); // 2 var standardIndex = numbers.Length - 2; var last2Num = numbers.Where((w, i) => i >= standardIndex); Console.WriteLine(String.Join(',', last2Num)); // 3 var strArray = numbers.Select(s => s.ToString()); Console.WriteLine(String.Join(',', strArray)); // 4 var alignedArray = numbers.OrderBy(x => x).Where((s, i) => i < 3); Console.WriteLine(String.Join(',', alignedArray)); // 5 var noDuplicationCount = numbers.Distinct().Count(c => c > 10); Console.WriteLine(noDuplicationCount);
리뷰
2. 예제 코드 보면서 이렇게 할 수 도 있구나 확인하기
4. Take 메서드 안 익숙해서 코드 작성할 때 생각이 안 난다. Take 메서드 기억하기!
예제 코드
class Program { static void Main(string[] args) { var numbers = new int[] { 5, 10, 17, 9, 3, 21, 10, 40, 21, 3, 35 }; Exercise1_1(numbers); Console.WriteLine("-----"); Exercise1_2(numbers); Console.WriteLine("-----"); Exercise1_3(numbers); Console.WriteLine("-----"); Exercise1_4(numbers); Console.WriteLine("-----"); Exercise1_5(numbers); } private static void Exercise1_1(int[] numbers) { var max = numbers.Max(); Console.WriteLine(max); } private static void Exercise1_2(int[] numbers) { var skip = numbers.Length - 2; foreach (var n in numbers.Skip(skip)) Console.WriteLine(n); } private static void Exercise1_3(int[] numbers) { var strs = numbers.Select(n => n.ToString()); foreach (var s in strs) Console.WriteLine(s); } private static void Exercise1_4(int[] numbers) { foreach (var n in numbers.OrderBy(n => n).Take(3)) Console.WriteLine(n); } private static void Exercise1_5(int[] numbers) { var count = numbers.Distinct().Count(n => n > 10); Console.WriteLine(count); } }
문제 6.2
class Program { static void Main(string[] args) { var books = new List<Book> { new Book { Title = "C# 프로그래밍의 상식", Price = 38000, Pages = 378 }, new Book { Title = "람다식과 LINQ의 비밀", Price = 25000, Pages = 312 }, new Book { Title = "원더풀 C# 라이프", Price = 29000, Pages = 385 }, new Book { Title = "독학 병렬처리 프로그래밍", Price = 48000, Pages = 464 }, new Book { Title = "구문으로 배우는 C# 입문", Price = 53000, Pages = 604 }, new Book { Title = "나도 할 수 있는 ASP.NET MVC", Price = 32000, Pages = 453 }, new Book { Title = "재미있는 C# 프로그래밍 교실", Price = 25400, Pages = 348 }, }; // 1 var array1 = books.Where(w => w.Title == "원더풀 C# 라이프").Select(s => new { s.Price, s.Pages }).FirstOrDefault(); Console.WriteLine($"가격 = {array1.Price}, 페이지 수 = {array1.Pages}"); // 2 var array2 = books.Count(c => c.Title.Contains("C#")); Console.WriteLine(array2); // 3 var array3 = books.Where(c => c.Title.Contains("C#")).Average(a => a.Pages); Console.WriteLine(array3); // 4 var array4 = books.FirstOrDefault(s => s.Price >= 40000); Console.WriteLine(array4.Title); // 5 var array5 = books.Where(w => w.Pages < 40000).Max(m => m.Pages); Console.WriteLine(array5); // 6 var array6 = books.Where(w => w.Pages >= 400).OrderByDescending(o => o.Price); foreach (var item in array6) { Console.WriteLine(item.Title, item.Price); } // 6 var array7 = books.Where(w => w.Title.Contains("C#") && w.Pages <= 500); foreach (var item in array7) { Console.WriteLine(item.Title); } } } class Book { public string Title { get; set; } public int Price { get; set; } public int Pages { get; set; } }
리뷰
1.
var array1 = books.Where(w => w.Title == "원더풀 C# 라이프").Select(s => new { s.Price, s.Pages }).FirstOrDefault();
아래 코드 처럼 쓸 걸 왜 더 복잡하게 작성했지?!
var array1 = books.FirstOrDefault(w => w.Title == "원더풀 C# 라이프");
예제 코드
class Program { static void Main(string[] args) { var books = new List<Book> { new Book { Title = "C# 프로그래밍의 상식", Price = 38000, Pages = 378 }, new Book { Title = "람다식과 LINQ의 비밀", Price = 25000, Pages = 312 }, new Book { Title = "원더풀 C# 라이프", Price = 29000, Pages = 385 }, new Book { Title = "독학 병렬처리 프로그래밍", Price = 48000, Pages = 464 }, new Book { Title = "구문으로 배우는 C# 입문", Price = 53000, Pages = 604 }, new Book { Title = "나도 할 수 있는 ASP.NET MVC", Price = 32000, Pages = 453 }, new Book { Title = "재미있는 C# 프로그래밍 교실", Price = 25400, Pages = 348 }, }; Exercise2_1(books); Console.WriteLine("-----"); Exercise2_2(books); Console.WriteLine("-----"); Exercise2_3(books); Console.WriteLine("-----"); Exercise2_4(books); Console.WriteLine("-----"); Exercise2_5(books); Console.WriteLine("-----"); Exercise2_6(books); Console.WriteLine("-----"); Exercise2_7(books); } private static void Exercise2_1(List<Book> books) { var book = books.FirstOrDefault(b => b.Title == "원더풀 C# 라이프"); if (book != null) Console.WriteLine("{0} {1}", book.Price, book.Pages); } private static void Exercise2_2(List<Book> books) { int count = books.Count(b => b.Title.Contains("C#")); Console.WriteLine(count); } private static void Exercise2_3(List<Book> books) { var average = books.Where(b => b.Title.Contains("C#")) .Average(b => b.Pages); Console.WriteLine(average); } private static void Exercise2_4(List<Book> books) { var book = books.FirstOrDefault(b => b.Price >= 4000); if (book != null) Console.WriteLine(book.Title); } private static void Exercise2_5(List<Book> books) { var pages = books.Where(b => b.Price < 4000) .Max(b => b.Pages); Console.WriteLine(pages); } private static void Exercise2_6(List<Book> books) { var selected = books.Where(b => b.Pages >= 400) .OrderByDescending(b => b.Price); foreach (var book in selected) { Console.WriteLine("{0} {1}", book.Title, book.Price); } } private static void Exercise2_7(List<Book> books) { var selected = books.Where(b => b.Title.Contains("C#") && b.Pages <= 500); foreach (var book in selected) Console.WriteLine(book.Title); } } class Book { public string Title { get; set; } public int Price { get; set; } public int Pages { get; set; } }
728x90'Development > C#' 카테고리의 다른 글
[C#] 인덱서 (0) 2023.07.27 [프렉티컬 C#] Dictionary (0) 2023.07.27 [프렉티컬 C#] 문자열 처리 (0) 2023.07.26 [프렉티컬 C# 연습문제] 2부 - 1장 (0) 2023.07.25 [프랙티컬 C# 연습문제] 1부 - 3장 (0) 2023.07.15