deck:: Logseq/coding tip

- ## **► 배열 선언 및 초기화**
	- ### **◼︎ 1차원 배열**
		- #### **● 1부터 10까지를 요소로 가지는 배열 생성하기(2가지 방법)** #card
		  id:: 691ed199-9a79-4333-9bb2-7795990e158e
			- ```swift
			  var arr = Array(1...N)
			  var arr = (1...N).map{$0}
			  ```
		- #### **● 모든 요소가 0인 길이 10의 배열 생성하기** #card
		  id:: 691ed271-962d-434b-9850-a7e3220421a5
			- ```swift
			  var arr = Array(repeating: 0, count: 10)
			  ```
	- ### **◼︎ 2차원 배열**
		- #### **● 모든 요소가 0인 N*M 크기의 배열 생성** #card
		  id:: 5ff9dc64-e39e-45a5-8c66-222619db3651
			- ```swift
			  var arr = Array(repeating: Array(repeating: 0, count: M), count: N)
			  ```
		- #### **● N*M 크기의 2차원 배열의 각 요소가 현 요소의 행과 열을 가지는 튜플이 되도록(1-base index)** #card
		  id:: f91d7c74-dd80-40c2-9a15-d9f5a0eeb61b
			- ```swift
			  var arr = (1...N).map{ row in
			      (1...M).map{ col in
			           (row, col)      
			      }
			  }
			  ```
-
- ## **► 비 고차 내장함수 모음**
	- ### **◼︎ stride()**
		- **정의**
			- 일정한 간격으로 숫자 {{c1 시퀀스}}를 생성하는 함수.
			  extra:: python의 range와 비슷함.
			  id:: 6960b576-ad59-4da0-bd9b-cdc8a293e99e
		- **파라미터**
			- stride의 파라미터는 {{c1 from}}, {{c1 to}}, {{c1 through}}, {{c1 by}} 이다.
			  extra:: (from, to, by) 혹은 (from, through, by) 조합으로 쓰인다.
			  id:: 6960b5b7-4154-4ed8-adc1-1f1d8d5b70d2
			- 파라미터 타입은 정수형(Int, Int8, UInt 등등)뿐 아니라 {{c1 실수형(Double, Float)}}도 가능하다.
			  id:: 6960b6dc-ce22-47fb-9d7c-2615053e8abd
			- stride(from: **a**, to: **b**, by: **c**) 의 의미는?
			  id:: 6960b6af-74bd-43cc-9124-eb59c73027d2
			  :-> a부터 시작해서 b까지 c 간격으로 시퀀스를 생성함(이때 b는 포함되지 않음)
			- stride(from: **a**, through: **b**, by: **c**) 의 의미는?
			  id:: 6960b79d-7044-4c17-953e-8e2eac6470f9
			  :-> a부터 시작해서 b까지 c 간격으로 시퀀스를 생성함(이때 b도 포함됨.)
		- **예제코드**
			- 0부터 1 사이를 역순으로 0.1간격으로 나눈 배열을 생성하라.(0은 포함하지 않는다) #card
			  id:: 6960b85a-b8e7-4a8b-a5b6-e5087647bfc7
				- ```swift
				  var arr = stride(from:1.0, to: 0.0, by: -0.1).map{$0}
				  var arr = Array(stride(from:1.0, to: 0.0, by: -0.1))
				  ```
			- 0부터 20까지 4의 간격으로 포함하는 배열을 생성하라(20은 포함된다) #card
			  id:: 6960b921-ae3e-4a8a-9430-2d56ec243992
				- ```swift
				  var arr = stride(from:0, through: 20, by: 4).map{$0}
				  var arr = Array(stride(from:0, through: 20, by: 4))
				  ```
-
- ## **► 고차함수 모음**
	- ### **◼︎ .map()**
		- #### **정의** #card
		  id:: 691edbcd-37ca-425c-85bb-f5ea0a45269d
			- 컨테이너(배열 등) 내부의 모든 요소에 대해 지정된 클로저(함수)를 실행하고, 그 결과를 모아 새로운 배열로 반환하는 고차함수.
			- 원본 배열을 수정하지 않는다.
		- #### **문법구조** #card
		  id:: 691edc68-64c5-4d4a-a2c1-1f67dbf503e1
			- ```swift
			  let result = numbers.map { number in
			      return number * 2
			  }
			  // 기본적으로 클로저를 입력받아서 실행됨.
			  // in 앞에는 컨테이너의 각 값을 의미하는 매개변수 명
			  // in 뒤에는 실행할 함수를 작성함.
			  
			  let result = numbers.map { $0 * 2 }
			  // 클로저 문법에 따라 입력 변수를 그냥 $0, $1 형태로 해서 바로 사용하는 것도 가능함
			  ```
	- ### **◼︎ .reduce()**
		- **기능**
			- {{c1 컬렉션(Collection)}}의 모든 요소를 순회하며, 주어진 {{c1 클로저(결합 규칙)}}를 적용해 {{c1 누적된 하나의 결과를 }} 반환하는 함수.
			  id:: 6975f46d-f557-41c8-871a-40e157662aa6
		- **사용형태 및 예시**
			- reduce() 기본형
				- 매 단계마다 {{c1 새로운 값을 생성(Return)}} 하여 다음 클로저의 첫번째 인자로 넘겨줌. 즉 결합 클로저의 반환타입이 reduce의 반환 타입과 일치해야함.
				  extra:: 숫자 합계 등 가벼운 데이터 타입 때 적합.
				  id:: 6975faa2-da0b-4182-8e54-b5035e84ad99
				- 배열 arr가 주어졌을 때 그 배열의 누적값 sum를 구하는 코드는 ? #card
				  id:: 6975fa93-e64e-4dea-972a-6ef9148b5618
					- ```swift
					  let arr = [1, 2, 3, 4]
					  let sum = arr.reduce(0, { (currentSum: Int, num: Int) -> Int in
					      return currentSum + num
					  })
					  
					  // 클로저 최적화 기법을 쓸 경우
					  let sum = arr.reduce(0){$0 + $1} // 후행 클로저
					  let sum = arr.reduce(0, +) // 연산자 자체가 이미 클로저
					  ```
			- reduce(into: ) 값 수정형
				- into 키워드로 넣어준 변수를 {{c1 수정하면서}} 값을 누적시킨다. 즉 결합클로저는 이 변수를 {{c1 수정하는 기능}}을 수행하기 때문에 클로저의 첫번째 인자는 {{c1 inout 타입}}으로 선언되어야 하고 반환 타입은 {{c1 void}} 이다.
				  extra:: 미리 선언한 변수를 into에 넣을 경우 그 원본변수는 수정되지 않고 reduce 함수 시작시 사용될 변수의 초기값이 그 원본변수의 값이 될 뿐이다.
				  id:: 6975fcf5-a69a-4abc-8a5c-88ea3f6ebbb7
				- 문자들의 배열 chars의 모든 요소를 합쳐서 하나의 문자열 str로 반환하라. #card
				  id:: 6975f952-6a13-45fd-b7a7-78815ca634a7
					- ```swift
					  let chars = ["a", "b", "c"]
					  let str = chars.reduce(into: "", { (result: inout String, char: String) in
					      result.append(char)
					  })
					  
					  //클로저 최적화
					  let str = chars.reduce(into: ""){$0.append($1)}
					  ```
				- 문자열 letters의 각 알파벳 별 빈도수를 출력하라 #card
				  id:: 6975feb8-3361-42c2-b913-2f7a70d731b6
					- ```swift
					  let letters = "abracadabra"
					  
					  // 딕셔너리에 문자별 등장 횟수 누적
					  let counts = letters.reduce(into: [:]) { (counts, letter) in
					      counts[letter, default: 0] += 1
					  }
					  
					  print(counts) 
					  ```
	- ### **◼︎ .contains()**
		- ### **정의**
			- 컬렉션에 특정 요소가 포함되어 있는지 확인하여 {{c1 Bool(true/false)}} 값을 반환한다.
			  id:: 6987060f-b1a1-4deb-90dc-8f8f69a40d15
		- ### **사용법**
			- **String(문자열)**
				- 문자열 내부의 부분 문자열 포함 여부를 확인한다. (대소문자 구분함)
				  id:: 69870822-687f-409d-a247-e787328368a5
				  **Code:**
				  ```swift
				  let message = "Hello, Swift World!"
				  
				  // 기본 사용
				  let hasSwift = message.contains("Swift")
				  let hasLowerCase = message.contains("swift")
				  let hasIgnoredCase = message.lowercased().contains("swift")
				  ```
				    
				  hasSwift, hasLowerCase, hasIgnoredCase 변수의 값은 각각 무엇일까?
				  #card
					- hasSwift : true
					- hasLowerCase : false
					- hasIgnoredCase : true
			- **Array(배열)**
				- 배열 안의 특정 요소를 찾는다.
				  id:: 69870822-58f6-4fef-97ad-cb2005b13180
				  **Code:**
				  ```swift
				  let numbers =[4, 6, 16, 17, 18]
				  let fruits = ["Apple", "Banana", "Cherry"]
				  
				  let hasFive = numbers.contains(5)
				  let hasGrape = fruits.contains("Grape")
				  ```
				    
				  hasFive, hasGrape 변수의 값은?
				  #card
					- hasFive : false
					- hasGrape : false
			- **조건(Closure)을 만족하는 요소 찾기**
				- contains( {{c1 where:}} ) 메서드를 사용한다.
				  id:: 69870822-02bc-45bc-a967-7848332320a1
				  클로저가 true를 반환하는 요소를 찾는 즉시 탐색을 종료하고 true를 반환한다.
				- 예제1 - numbers 배열에 짝수가 하나라도 있는지 검사하는 코드를 작성하라. #card
				  id:: 698709ba-a5ae-4eb8-adb4-5766aae37832
					- ```swift
					  let numbers =[1, 2, 16, 17, 4]
					  
					  let hasEvenNumber = numbers.contains(where: { (number: Int) -> Bool in
					      return number % 2 == 0
					  })
					  
					  // 클로저 축약 및 후행 클로저 적용
					  let hasEvenNumber = numbers.contains{ $0 % 2 == 0 }
					  ```
			- **Dictionary(딕셔너리)에서 사용**
				- contains(where:) 메서드를 활용해서 클로저를 활용해서 조건을 찾는다.
				  id:: 69870a4c-f7bf-42a7-bec9-4bd02966bad0
				  이때 클로저에 전달되는 매개변수는 {{c1 (key, value)의 튜플}} 이다.
				- 예제 - 이름(문자열) : 점수(정수)로 구정된 scores 딕셔너리에서 90점이 넘는 사람이 있는지 검사하는 코드를 작성하라 #card
				  id:: 69870cbb-f2af-494a-bb49-92a1126ad5a7
					- ```swift
					  let scores = ["Alice": 90, "Bob": 80, "Charlie": 85]
					  
					  // "점수가 90점인 사람이 있는가?"
					  let hasPerfectScore = scores.contains(where: { (key: String, value: Int) -> Bool in
					      return value > 90
					  })
					  
					  // 매개변수가 튜플 하나이므로 각 요소를 $0.key, $0.value로 접근 해서 축약 및 후행클로저 사용 가능
					  let hasPerfectScoreSimple = scores.contains { $0.value > 90 }
					  ```
		-
-
- ## **► 클로저(Closure)**
	- ### **◼︎ 정의** #card
	  id:: 69203197-090a-42f4-9a92-16efb9516eca
		- swift에서 사용되는 익명함수 기능을 통칭하는 용어
		- 일급 객체로서 변수/상수에 저장도 가능하고 함수의 파라미터로 전달하거나 리턴값으로 사용 가능.
	- ### **◼︎ 문법**
		- **● 기본문법** #card
		  id:: 6920321b-21c3-4661-a415-debd1460f764
			- ```swift
			  // 기본 형태
			  {(매개변수) -> 반환타입 in 실행구문}
			  
			  // 변수 대입
			  let sum_nums = {(a: Int, b: Int) -> Int in return a+b}
			  ```
		- **● 문법최적화(sorted 함수를 기준으로 단계별로 최적화 되는 것을 설명)** #card
		  id:: 69203294-17a2-4c7e-a0af-e3811397d73b
			- ```swift
			  // 0. 전체 문법
			  let sorted0 = nums.sorted(by: {(a: Int, b: Int) -> Bool in 
			      return a < b
			  })
			  
			  // 1. 타입유추
			  // 파라미터의 타입을 추정할 수 있다면 생략이 가능하다
			  let sorted1 = nums.sorted(by: {(a, b) in 
			      return a < b
			  })
			  
			  // 2. 암시적 변환
			  // 클로저 내부의 코드가 단 한줄이면 return 키워드를 생략 가능
			  let sorted2 = nums.sorted(by: {(a, b) in 
			      a < b
			  })
			  
			  // 3. 단축 인자 이름
			  // 매개변수도 생략하고 첫번째 인자는 $0, 두번째 인자는 $1 로 해서 사용가능
			  let sorted3 = nums.sorted(by: { 
			  	$0 < $1
			  })
			  
			  // 4. 후행클로저
			  // 함수의 매개변수 중 클로저가 1개이고 가장 마지막으로 들어가는 인자일 경우
			  // 클로저 자체의 중괄호를 소괄호 밖으로 뺄 수 있음
			  // 고차함수의 인자가 클로저 1개 뿐일 경우에는
			  // 소괄호 자체도 생략해서 클로저만 붙이는것도 가능
			  let sorted4_1 = nums.sorted(){$0 < $1}
			  let sorted4_2 = nums.sorted{$0 < $1}
			  
			  // 참고사항
			  // 연산자는 (<, >) 그 자체로 이미 클로저이기에 바로 넘길 수 있음
			  let sorted5 = nums.sorted(by: <)
			  ```