작성자 드 브리스 2020 년 7 월 9 일 앱 개발,스위프트

스위프트

에서 매핑,축소 및 필터링 스위프트에서는map(),reduce()filter()을 사용하여 루프를 사용하지 않고 배열 및 사전과 같은 컬렉션을 반복합니다.

지도,감소 및 필터 함수는 함수형 프로그래밍 영역에서 나옵니다. 그들은 함수를 입력으로 사용하기 때문에 고차 함수라고합니다. 예를 들어 배열에 함수를 적용하여 데이터를 변환하고 있습니다.

스위프트의지도,감소 및 필터 기능은 도전 주위에 당신의 머리를 감싸 할 수 있습니다. 특히 반복 문제를 해결하기 위해 항상for in루프를 코딩 한 경우. 이 가이드에서는 스위프트에서map(_:),reduce(_:_:)filter(_:)기능을 사용하는 방법을 배웁니다.

시작하자!

  1. 매핑,축소 및 필터 소개
  2. 빠른 시작: 스위프트의 고차 함수
  3. 맵 기능 사용
  4. 필터 기능 사용
  5. 맵,축소 및 필터링 결합
  6. 추가 읽기

맵,축소 및 필터링 소개

앱은 일반적으로 절차 적 또는 객체 지향 프로그래밍을 사용합니다. 함수형 프로그래밍은 다릅니다:함수 만 다룹니다. 변수 없음,상태 없음,루프 없음-함수.

스위프트 프로그래밍 언어는 함수형 프로그래밍과 비 기능적 접근 방식을 혼합하는 데 완벽하게 적합합니다. 함수형 코드를 엄격하게 작성할 필요는 없으며 함수형 프로그래밍에서 개념을 채택하면 더 잘 코딩하는 방법을 배울 수 있습니다.

map(_:),reduce(_:_:)filter(_:)함수는 함수를 입력으로 사용하고 반환 함수를 출력으로 사용하기 때문에 고차 함수라고 합니다. 기술적으로 스위프트는 작업 결과를 반환합니다(예: 변환 된 배열)고차 함수를 사용하는 경우 순수한 함수 언어는 함수 컬렉션을 반환합니다. 스위프트에서는 이러한 함수에 대한 입력이 클로저입니다.

작동 방식:

  • map()함수는 컬렉션의 모든 항목에 함수를 적용합니다. 한 값 집합을 다른 값 집합으로”매핑”하거나 변환하는 것을 생각해보십시오.
  • reduce()함수는 컬렉션을 하나의 값으로 바꿉니다. 숫자 집합의 평균과 같이 많은 값을 하나로 결합하는 것으로 생각하십시오.
  • filter()함수는 단순히if-문을 전달한 값을 반환하며,해당 조건이true가 발생한 경우에만 반환됩니다.

당신이 생각하는 경우:”내 앱이 그렇게하지 않기 때문에 함수형 프로그래밍이나 데이터 처리가 필요하지 않습니다!”그럼 여기서 멈추지 마. 최근 앱 프로젝트에서는 여러 차례 맵,축소 및 필터를 사용했습니다:

  • filter(_:)로 비용/수익 값을 필터링하여 선 그래프에 값을 표시하기 전에 임계 값을 충족
  • reduce(_:_:)
  • 와 함께 수천 개의 영화 등급을 하나의 값으로 평균화 해시 태그가있는 문자열에 대한 몇 가지 작업을 매핑하여 정규화 된 컬렉션으로 변환하고,10000000000000000000map(_:)

루프로 이러한 모든 문제를 해결할 수 있었지만map(),reduce()filter()을 사용하면 더 간결하고 읽기 쉽고 성능이 뛰어난 코드가 생성됩니다.

빠른 시작: 스위프트의 고차 함수

이 자습서에서는map(),reduce()filter()에 중점을 둡니다. 우리가 이동하기 전에,여기에 스위프트에서 가장 일반적인 고차 함수에 대한 간략한 개요입니다:

  • map(_:) 시퀀스의 모든 항목을 반복하고 각 요소에 함수를 적용하고 변환 된 결과를 반환
  • reduce(_:_:)시퀀스의 모든 항목을 반복하고 하나의 값으로 결합하고 결합 된 결과를 반환합니다
  • filter(_:)시퀀스의 모든 항목을 반복하고 주어진 필터링 함수를 만족하는 항목 만 포함하는 결과 시퀀스를 반환합니다
  • flatMap(_:)map(_:)과 동일하며,
  • flatMap(_:)는 결과 시퀀스를 평평하게하는 것을 제외하고,즉 중첩 배열은 중첩되지 않거나”평면화”됩니다”
  • compactMap(_:)

반환하기 전에 결과 시퀀스에서nil값을 제거한다는 점을 제외하고map(_:)과 동일합니까 배열,사전,집합,범위,시퀀스 및 반복 할 수있는 기타 스위프트 유형에서 이러한 함수를 사용할 수 있습니다. compactMap(_:)flatMap(_:)에 대해 자세히 알고 싶다면 이 자습서를 확인하십시오.

배열 및 사전과 같은 스위프트의 여러 유형에는 클로저를 입력으로 받아들이는 함수가 있습니다. 빠른 선택:

  • contains(where:) 컬렉션을 반복하고,모든 항목에 조건자(클로저)를 적용하고,항목이 조건자를 만족하는 경우true를 반환합니다.false
  • first(where:) 컬렉션을 반복하고 술어(클로저)를 모든 항목에 적용하고 술어
  • firstIndex(where:)를 만족하는 경우 항목을 반환합니다.

값 대신 인덱스를 반환한다는 점을 제외하고는first(where:)와 동일합니다.이 자습서에서는 이러한 함수에 대해 자세히 알아볼 수 있습니다. 스위프트에서where를 사용하는 방법도 흥미 롭습니다.이 자습서에서 더 자세히 배울 수 있습니다.

이 자습서를 통해map(_:)reduce(_:_:)로 작성된 스위프트의”맵”및”축소”기능을 보았습니다. 이러한 함수의 밑줄과 콜론은 함수 시그니처의 일부이며 함수 매개 변수를 나타내는 특수 형식입니다. 예를 들어map(_:)함수에는 이름이 지정되지 않은 매개 변수가 하나 있는 반면reduce(_:_:)함수에는 두 개가 있습니다. 이 튜토리얼에서 그에 대한 자세한 내용을 배울 수 있습니다:스위프트의 기능은 설명했다.

을 얻으로 고용자

를 구축하는 것을 배우십시오 iOS14 앱을 신속한 5

내 iOS 개발 과정,그리고 시작하는 방법에 대해 알아보십시오 경력으로 전문 iOS 개발자이다.

맵 함수 사용

map(_:)함수는 컬렉션의 모든 항목을 반복하고 컬렉션의 각 요소에 작업을 적용합니다. 작업이 적용된 결과 항목의 컬렉션을 반환합니다.

의 예를 살펴 보자. 우리는 화씨로 변환 할 섭씨 온도의 배열을 가지고있다.

다음과 같이 루프를 사용할 수 있습니다:

let celsius = var fahrenheit: = for value in celsius { fahrenheit += }print(fahrenheit)// Output: 

코드는 잘 작동하지만 너무 장황합니다. 계산 된 변환을 통해 작업 할 때 저장하려면 변경 가능한”도우미”변수fahrenheit가 필요하며 변환 자체에 대해 3 줄의 코드가 필요합니다.

map(_:)함수로 동일한 작업을 수행 할 수있는 방법은 다음과 같습니다.:

하자 섭씨=
하자 화씨=섭씨.지도{ $0 * (9/5) + 32 }
인쇄(화씨)
경고 숨기기

한 줄로 모든 작업을 수행 할 수도 있습니다.:

.map {  * (9/5) + 32 }

여기서 무슨 일이 일어날까요?

  1. 상수celsius는 이중 배열로 정의되고 몇 개의 임의의 섭씨 값으로 초기화됩니다.
  2. 함수map(_:)celsius배열에서 호출됩니다. 이 함수에는 섭씨에서 화씨로 변환하는 하나의 인수 인 클로저가 있습니다.
  3. 마지막으로 결과가 출력됩니다:섭씨에서 화씨로 변환 된 배열.

map(_:)함수는 배열의 모든 항목에 함수를 적용하여 한 배열을 다른 배열로 변환합니다. 폐쇄 * (9/5) + 32는 입력 값을 섭씨로 취하고 화씨 값을 반환합니다. map(_:)의 결과 배열은 이러한 변환된 값에서 빌드됩니다.

의 폐쇄에 대해 자세히 살펴 보자. 이전에 클로저로 작업 한 적이 있다면 짧은 손 클로저 구문을 인식 할 수 있습니다. 그것은 그것의 구문의 대부분을 떠나,폐쇄를 코딩하는 짧은 방법입니다.

다음은 덜 간결한 대안입니다:

let celsius = let fahrenheit = celsius.map({ (value: Double) -> Double in return value * (9/5) + 32})print(fahrenheit)

실제map(_:)함수 호출 및 클로저는 다음과 같습니다:

··· = celsius.map({ (value: Double) -> Double in return value * (9/5) + 32})

무슨 일이야? map(_:)함수는 배열celsius에서 호출됩니다. 하나의 인수가 필요합니다:(Double) -> Double유형의 폐쇄.

{로 시작하는 클로저의 첫 번째 부분은 이 클로저에Double형식의 매개 변수value이 하나 있고 클로저에는Double형식의 값이 반환됨을 나타냅니다. return로 시작하는 폐쇄 본체는 단순히 섭씨에서 화씨 계산 결과를 반환합니다.

짧은 손 클로저 구문을 위의 확장 코드와 비교하면 다음과 같이 표시됩니다:

  • 함수 괄호()은 생략됩니다.
  • () -> in부분은 생략할 수 있습니다. 이제value변수를 제외했으므로 짧은 손을 사용할 수 있습니다.
  • return문도 생략할 수 있습니다.

위의 코드 샘플에서Double유형을 사용하더라도 이러한 유형에만 국한되지 않습니다. map()함수의 결과 형식은 입력한 것과 다른 형식을 가질 수 있으며Dictionarymap()도 사용할 수 있습니다.

reduce(_:_:)로 넘어가자!

축소 함수 사용

reduce(_:_:)함수는 컬렉션의 모든 항목을 반복하여 하나의 값으로 줄입니다. 여러 값을 하나로 결합하는 것으로 생각하십시오.

축소 기능은 아마도 맵,축소,필터 중에서 가장 이해하기 어려운 기능일 것입니다. 값 모음에서 하나의 값으로 어떻게 갈 수 있습니까?

몇 가지 예:

  • 여러 값의 합계 생성,즉3 + 4 + 5 = 12
  • 문자열 모음 연결,즉 = "Zaphod, Trillian, Ford"
  • 값 집합 평균(7 + 3 + 10) / 3 = 7/3 + 3/3 + 10/3 = 6.667

데이터 처리에서 이와 같은 간단한 작업이 유용 할 때 많은 시나리오를 상상할 수 있습니다. 이전과 마찬가지로 이러한 문제 중 하나를 루프로 해결할 수 있지만reduce(_:_:)는 더 짧고 빠릅니다.

방법은 다음과 같습니다:

값=
하자 합계=값을 보자.축소(0,+)
인쇄(합계)
경고 숨기기

함수reduce(_:_:)는 초기 값과 클로저의 두 인수를 사용합니다. 위의 코드에서 우리는+연산자를 제공하고,이 또한 두 개의 매개 변수를 가진 함수입니다.

당신은 또한 당신의 자신의 마감을 제공할 수 있습니다,당연히:

값=
평균=값을 보자.감소(0.0) { $0 + $1 } / 더블(값.개수)
인쇄(평균)
경고 숨기기

위의 예제에서는 세 숫자의 평균을 계산합니다. 코드의 값 형식은 모두Double입니다. 우리는 먼저 모든 숫자를 더하고 숫자의 양으로 나눕니다.

reduce(_:_:)함수는 두 가지 방법으로 다릅니다:

  1. 초기 값과
  2. reduce(_:_:)에 제공된 클로저에는 두 개의 매개 변수도 있습니다; 감소의 현재 결과 및 감소 될 새 값

여기,이 체크 아웃:

값=
하자 합계=값을 보자.축소(0){
인쇄(“\($0) + \($1) = \($0 + $1)”)
반환$0 + $1
}
인쇄(합계)
경고 숨기기

위의 예에서,클로저의 2 매개 변수를 명확하게 볼 수 있습니다. 당신이 코드를 실행할 때,이것은 당신이 얻을 출력입니다:

0 + 7 = 77 + 3 = 1010 + 10 = 2020

0로 시작한 다음7를 추가하는 방법을 참조하십시오. 다음 단계에서는 현재 감소 값 인7를 취하고 감소에”다음”값인3을 추가합니다.

여기 그것을 보는 또 다른 방법이 있습니다:

0 + 7(0 + 7) + 3((0 + 7) + 3) + 10

이것은 또한 클로저의 첫 번째 첫 번째 매개 변수이기 때문에reduce(_:_:)에 대한 초기 값이 필요한 이유를 분명히합니다.

감소는 파악하기 까다로울 수 있습니다. 하나의 값만 남을 때까지+와 같은 작업을 값 집합에 반복적으로 적용한다는 것을 이해하는 것이 중요합니다. 당신은 문자 그대로 값의 양을 줄일 수 있습니다.

filter(_:)로 넘어가자!

필터 함수 사용

filter함수는 컬렉션의 모든 항목을 반복하고 포함 조건을 만족하는 항목만 포함하는 컬렉션을 반환합니다.

컬렉션에if-문을 적용하고 조건을 전달하는 값만 유지하는 것과 같습니다.

여기,이 체크 아웃:

값=
짝수=값을 보자.필터{$0.이 문제를 해결하는 방법은 무엇입니까?)
경고 숨기기

위의 예제에서는values에서 짝수 인 숫자를 필터링합니다. isMultiple(of:)함수는2로 나눌 수 있고false이 그렇지 않으면true를 반환합니다.

map(_:)reduce(_:_:)와 달리 클로저filter(_:)true또는false중 부울을 반환해야합니다. 클로저가true를 반환하면 값이 유지되고false이 반환되면 값이 생략됩니다. 이것이filter(_:)가 입력 배열을 필터링하는 방법입니다.

클로저가 확장 된 약간 더 명확한 예가 있습니다.:

let values = let even = values.filter({ (value:Int) -> Bool in return value.isMultiple(of: 2)})print(even) // Output: 

이 예에서 클로저는-> Bool로 표시된 부울 값을 반환합니다. 하나의 매개 변수,컬렉션의 항목을 제공 하 고isMultiple(of:)의 결과 반환 합니다. 깔끔한!

지도 결합,축소 및 필터링

map(),reduce()filter()기능을 결합 할 수 있습니까? 물론 당신은 할 수 있습니다!

의 우리는 학생들의 클래스가 있다고 가정 해 봅시다. 당신은 각 학생이 태어난 해를 알고 있습니다. 2000 년 또는 그 이후에 태어난 모든 학생의 결합 된 나이를 계산하려고합니다.

이렇게 하는 방법은 다음과 같습니다.:

이제 보자=2020
하자 년=
하자 합계=년.필터({ $0 >= 2000 }).지도({지금-$0}).축소(0,+)
인쇄(합계)
경고 숨기기

위의 코드 샘플에서는 체인을 사용합니다. 한 함수의 결과를 다른 함수에 대한 입력으로 사용하여 맵 감소 필터를 결합합니다. map()함수는filter()함수의 결과 배열에서 호출되고reduce()함수는map()함수의 결과에 호출됩니다. 최고!

코드 자체는 간단합니다.:

  1. 상수nowyears를 만들고 몇 년을 할당하십시오.
  2. 2000 년 이하의 연도를 필터링합니다. >= 2000true
  3. 인 연도를now
  4. 에서 연도를 빼서 모든 연령대를 더하고 각 연도를 연령으로 변환합니다.+

좀 더 흥미로운 예를 들어 보겠습니다. 다음 코드를 확인하십시오.:

나는 내가 할 수있는 모든 것을 가지고 있다고 생각한다.% 5 == 0)
{
예를 들어,두 개의 대/소문자를 구분할 수 있으며,두 개의 대/소문자를 구분할 수 있습니다.:
반환”\(나는)”
}
}
결과=배열(2…100).지도(피즈 버즈).감소(“1”, { $0 + “, ” + $1 })
인쇄(결과)
경고 숨기기

무슨 일이야? 우리는 게임의 규칙에 따라 2 에서 100 까지의 숫자를 가진 배열을”피즈”,”버즈”또는”피즈 버즈”로map(_:)로 변환합니다. 마지막으로 문자열 배열을reduce(_:_:)가있는 하나의 큰 문자열로 줄이고 모든 값을 결합합니다. 깔끔한!

추가 읽기

이 모든 것을for in루프로 코딩해야한다면 어떨까요? 당신은 더 많은 코드를 사용할 것입니다. 그리고 그지도-감소-필터의 힘이다:그것은 읽기 종종 쉽게,더 간결하고,—그것을 인정-아주 빌어 먹을 멋진!

더 알고 싶으십니까? 이러한 리소스를 확인하십시오:

  • 스위프트
  • 에서”위치”를 사용하는 방법 플랫 맵과 컴팩트 맵 스위프트
  • 에서 설명 스위프트
  • 에서 클로저에 대한 궁극적 인 가이드 방법:스위프트
  • 에서 배열에서 항목 찾기 코드로 재생: 바이너리에서 검색 스
  • 시작 Xcode 놀이터

을 얻으로 고용자

를 구축하는 것을 배우십시오 iOS14 앱을 신속한 5

내 iOS 개발 과정,그리고 시작하는 방법에 대해 알아보십시오 경력으로 전문 iOS 개발자이다.

답글 남기기

이메일 주소는 공개되지 않습니다.