Map과 FlatMap, CompactMap

2022. 3. 21. 22:58iOS/Swift 문법

스위프트는 함수를 일급 객체(First class)로 취급하기 때문에 함수를 다른 함수의 전달인자로 사용할 수 있다. 매개 변수로 함수를 갖는 함수를 고차 함수(Higer order function)라고 한다.

이와 같은 함수 고차함수를 사용하는 이유는 다음과 같다

  • 코드의 재사용
  • 컴파일러 최적화
  • 다중 스레드 환경 시 안전함

   책과 블로그를 통해서 개념이 잘 와닿지 않는 다면 문제를 풀어보는 것도 좋은 방법이다. 고차 함수를 이용해서 코드 작성해본다면 왜 쓰는지, 어떤 의미인지 알게 될 것이다.

   클로저에서 파라미터와 반환 타입과 return 키워드는 생략이 가능하다.

Map

매개변수로 전달된 함수를 실행하여 그 결과를 다시 반환해주는 함수

Sequence와 Collection 프로토콜을 따르는 타입과 옵셔널에서 사용한다.

기존 데이터를 변형하는데 많이 사용된다.

CompactMap

Optional 제거를 위한 FlatMap은 CompactMap으로 대체되었음. 기능이 동일함

FlatMap

Optional이 섞여있는 collection에서 Optional을 제거할 수 있다.

여러 차원의 collection 값들을 한 차원으로 변형해준다. 이름 그대로 Flat하게 만들어 준다.

 

struct Song {
    var genre: String
    var plays: Int
    var id: Int
}

struct SongInfo {
    var total: Int
    var songs: [(plays: Int, id: Int)]
}

func solution(_ genres:[String], _ plays:[Int]) -> [Int] {

    var genreMap = Dictionary<String, SongInfo>()

    genres
        .enumerated()
        .map { genre in
            Song(genre: genre.element, plays: plays[genre.offset], id: genre.offset)
        }.forEach { song in
            let data = genreMap[song.genre, default: SongInfo(total: 0, songs: [])]
            let total = data.total + song.plays
            let songs = data.songs + [(plays: song.plays, id: song.id)]
            genreMap[song.genre] = SongInfo(total: total, songs: songs)
            genreMap[song.genre]?.songs
                .sort(by: {
                    if $0.plays == $1.plays {
                        return $0.id < $1.id
                    } else {
                        return $0.plays > $1.plays
                    }
                })
            let pre = (genreMap[song.genre, default: SongInfo(total: 0, songs: [])].songs.prefix(2).map({
                $0
            }))
            genreMap[song.genre]?.songs = pre
        }
    let b =
    genreMap.sorted { a, b in
        a.value.total > b.value.total
    }
    .flatMap { $0.value.songs }
    .map { $0.id }
    print(b)
    return b
}
solution(genres, plays)

 

https://programmers.co.kr/learn/courses/30/lessons/42579

 

코딩테스트 연습 - 베스트앨범

스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다. 속한 노래가

programmers.co.kr

 

참고

[Swift] Functor and Monad in Swift 블로그

https://baked-corn.tistory.com/131