본문 바로가기

프로그래머스 PS일지/level1

[프로그래머스] Level1 - 추억점수 | PS일지

 
문제

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

간단한 문제 요약

(photo)사진들 속에 있는 (name)특정 인물들은 (yearning)그리움 점수가 있습니다. 각각의 사진이 주어질 때 사진 속에 특정 인물들의 그리움 점수를 합산 한 값을 배열로 완성해주세요.
 

문제 풀이

photo에서 각각의 배열에는 특정 사진 속 인물들의 이름이 있습니다. photo.map을 사용해서 각각의 사진속 특정 인물들의 배열을 얻어온 후에 그 특정 사진의 인물들이 name에 존재하는가? firstIndex(of:)함수를 통해 index가 반환된다면 yearning 그리움이 값을 더해가며 사진 속 그리움 값을 계산해 나갔습니다.
 

func solution( _ name:[String], _ yearning:[Int], _ photo:[[String]]) -> [Int] {
  return photo.map {
    $0.reduce(0) {
      guard let idx = name.firstIndex(of: $1) else { return $0 }
      return $0 + yearning[idx]
    }
  }
}

 
코드 개선점을 찾다 다른 분의 코드를 봤는데 딕셔너리를 써도 좋았을 것 같다는 생각을 했습니다.
 

func solution(_ name:[String], _ yearning:[Int], _ photo:[[String]]) -> [Int] {
    let score: [String: Int] = Dictionary(uniqueKeysWithValues: zip(name, yearning))
    return photo.map { $0.reduce(0) { $0 + (score[$1] ?? 0) } }
}

//honghoker님 코드

Dictionary의 init(uniqueKeysWithValues:) 는 주어진 keysAndValues를 통해 key-value pair를 만들어서 저장합니다.
 

 
이때 S는 sequence여야 하고, sequence 각각의 Element는 (Key,Value) 타입이어야 합니다. 이는 zip(_:_:) 함수를 통해 연속적인 두개의 sequence를 위에서 만족하는 S 타입으로 만들 수 있습니다. 그래서 name과 yearning을 (Key,Value) 타입으로 하는 sequence로 만들 수 있고 이를 Dictionary로 생성할 수 있습니다.
 
굳이 왜 딕셔너리를 만들까? 할 수도 있지만,
 

 
딕셔너리의 subscript(key:)를 통해 딕셔너리 내 존재하는 key가 아닐 경우 옵셔널을 반환할 수 있고, 이는 위에서 제가 사용했던 firstIndex(of:)를 대체할 수 있습니다. +_+

photo내 특정 인물들이 존재하지 않을 경우 key(name에 이름 존재 x)가 존재하지 않기 때문에 옵셔널 타입을 반환합니다. 이는 0으로 ?? 연산자 swift nil-coalescing operator로 변환할 수 있습니다.