From 0dc4e4c53a76cfc35896204ec8fb02c192db4815 Mon Sep 17 00:00:00 2001 From: Seonghun Date: Tue, 12 Nov 2019 13:46:19 +0900 Subject: [PATCH 1/7] =?UTF-8?q?1=E1=84=8E=E1=85=A1=20=E1=84=89=E1=85=AE?= =?UTF-8?q?=E1=84=8C=E1=85=A5=E1=86=BC=20=E1=84=87=E1=85=A5=E1=84=8C?= =?UTF-8?q?=E1=85=A5=E1=86=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tutorial/Tutorial.playground/Contents.swift | 22 ++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Tutorial/Tutorial.playground/Contents.swift b/Tutorial/Tutorial.playground/Contents.swift index 9b0d9f6..85e6202 100644 --- a/Tutorial/Tutorial.playground/Contents.swift +++ b/Tutorial/Tutorial.playground/Contents.swift @@ -28,5 +28,25 @@ let champs = try JSONSerialization.jsonObject(with: champsData!, options: []) let selectedIndexes = try JSONSerialization.jsonObject(with: selectedIndexesData!, options: []) // TODO: selectedIndexes는 챔피언 목록(champs)의 key 번호 들이다. selectedIndexes에 명시된 순서대로 챔피언들의 이름(name)을 나열하라 -let names: [String] = [] +var names: [String] = [] + +let champList = (champs as? [[String: Any]]) ?? [] +let selectedIndexList = (selectedIndexes as? [Int]) ?? [] + +let temp = champList + .filter { + guard let index = Int(($0["key"] as? String) ?? "") else { return false } + return selectedIndexList.contains(Int(($0["key"] as? String) ?? "") ?? -1) +} + +selectedIndexList.forEach { index in + let value = temp.filter { + guard let indexValue = Int(($0["key"] as? String) ?? "") else { return false } + return index == indexValue + } + .compactMap { $0["name"] as? String } + .first + names.append(value ?? "") +} + print(names) From a13f8fa605573d1f4fa1a9bdbf6c02ba4b22dfbc Mon Sep 17 00:00:00 2001 From: Seonghun Date: Tue, 12 Nov 2019 14:41:04 +0900 Subject: [PATCH 2/7] =?UTF-8?q?=E1=84=83=E1=85=AE=E1=84=87=E1=85=A5?= =?UTF-8?q?=E1=86=AB=E1=84=8D=E1=85=A2=20=E1=84=89=E1=85=AE=E1=84=8C?= =?UTF-8?q?=E1=85=A5=E1=86=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tutorial/Tutorial.playground/Contents.swift | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Tutorial/Tutorial.playground/Contents.swift b/Tutorial/Tutorial.playground/Contents.swift index 85e6202..b9ffd8f 100644 --- a/Tutorial/Tutorial.playground/Contents.swift +++ b/Tutorial/Tutorial.playground/Contents.swift @@ -31,22 +31,22 @@ let selectedIndexes = try JSONSerialization.jsonObject(with: selectedIndexesData var names: [String] = [] let champList = (champs as? [[String: Any]]) ?? [] -let selectedIndexList = (selectedIndexes as? [Int]) ?? [] +let selectedIndexList = ((selectedIndexes as? [Int]) ?? []).compactMap { String($0) } -let temp = champList - .filter { - guard let index = Int(($0["key"] as? String) ?? "") else { return false } - return selectedIndexList.contains(Int(($0["key"] as? String) ?? "") ?? -1) -} +let temp: [[String: String]] = champList + .map { + guard let key = $0["key"] as? String, let name = $0["name"] as? String else { return nil } + return ["key": key, "name": name] + } + .compactMap { $0 } selectedIndexList.forEach { index in - let value = temp.filter { - guard let indexValue = Int(($0["key"] as? String) ?? "") else { return false } - return index == indexValue - } - .compactMap { $0["name"] as? String } + let value = temp + .filter { $0["key"] == index } + .compactMap { $0 } .first - names.append(value ?? "") + + names.append((value?["name"] as? String) ?? "") } print(names) From cbea9441c6ca216f4e93d38b608efa13e20553aa Mon Sep 17 00:00:00 2001 From: Seonghun Date: Tue, 12 Nov 2019 19:43:11 +0900 Subject: [PATCH 3/7] =?UTF-8?q?=E1=84=89=E1=85=A6=E1=84=87=E1=85=A5?= =?UTF-8?q?=E1=86=AB=E1=84=8D=E1=85=A2=20=E1=84=89=E1=85=AE=E1=84=8C?= =?UTF-8?q?=E1=85=A5=E1=86=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tutorial/Tutorial.playground/Contents.swift | 34 ++++++++------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/Tutorial/Tutorial.playground/Contents.swift b/Tutorial/Tutorial.playground/Contents.swift index b9ffd8f..ecc7156 100644 --- a/Tutorial/Tutorial.playground/Contents.swift +++ b/Tutorial/Tutorial.playground/Contents.swift @@ -24,29 +24,21 @@ let selectedIndexesFilePath = Bundle.main.path(forResource: "selectedIndexes", o let champsData = FileManager.default.contents(atPath: champsFilePath!) let selectedIndexesData = FileManager.default.contents(atPath: selectedIndexesFilePath!) -let champs = try JSONSerialization.jsonObject(with: champsData!, options: []) -let selectedIndexes = try JSONSerialization.jsonObject(with: selectedIndexesData!, options: []) +let champs = try JSONSerialization.jsonObject(with: champsData!, options: []) as? [[String: Any]] +let selectedIndexes = try JSONSerialization.jsonObject(with: selectedIndexesData!, options: []) as? [Int] // TODO: selectedIndexes는 챔피언 목록(champs)의 key 번호 들이다. selectedIndexes에 명시된 순서대로 챔피언들의 이름(name)을 나열하라 -var names: [String] = [] - -let champList = (champs as? [[String: Any]]) ?? [] -let selectedIndexList = ((selectedIndexes as? [Int]) ?? []).compactMap { String($0) } - -let temp: [[String: String]] = champList - .map { - guard let key = $0["key"] as? String, let name = $0["name"] as? String else { return nil } - return ["key": key, "name": name] +let names = selectedIndexes? + .compactMap { String($0) } + .compactMap { index in + champs?.first { $0["key"] as? String == index } } - .compactMap { $0 } - -selectedIndexList.forEach { index in - let value = temp - .filter { $0["key"] == index } - .compactMap { $0 } - .first - - names.append((value?["name"] as? String) ?? "") -} + .compactMap { $0["name"] as? String } + ?? [] print(names) + +// 코드는 깔끔해 졌으나 챔프를 탐색할 때 중복하여 탐색하게 되는 문제가 있다. +// 딕셔너리 배열이 아닌 딕셔너리로 탐색하면 비효율을 줄일 수 있을 것 같다. +// 딕셔너리 배열을 딕셔너리로 변경하려면 어떻게 해야 할까? +// 함수형으로 깔끔하게 변경하는 법을 좀 더 고민해야 겠다. From d8edd1b2b05583e7729b139d29809b19b061dbcb Mon Sep 17 00:00:00 2001 From: Seonghun Date: Tue, 12 Nov 2019 20:02:39 +0900 Subject: [PATCH 4/7] =?UTF-8?q?=E1=84=82=E1=85=A6=E1=84=87=E1=85=A5?= =?UTF-8?q?=E1=86=AB=E1=84=8D=E1=85=A2=20=E1=84=89=E1=85=AE=E1=84=8C?= =?UTF-8?q?=E1=85=A5=E1=86=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tutorial/Tutorial.playground/Contents.swift | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Tutorial/Tutorial.playground/Contents.swift b/Tutorial/Tutorial.playground/Contents.swift index ecc7156..78c94ac 100644 --- a/Tutorial/Tutorial.playground/Contents.swift +++ b/Tutorial/Tutorial.playground/Contents.swift @@ -28,17 +28,20 @@ let champs = try JSONSerialization.jsonObject(with: champsData!, options: []) as let selectedIndexes = try JSONSerialization.jsonObject(with: selectedIndexesData!, options: []) as? [Int] // TODO: selectedIndexes는 챔피언 목록(champs)의 key 번호 들이다. selectedIndexes에 명시된 순서대로 챔피언들의 이름(name)을 나열하라 + +let champsDict = champs? + .flatMap { [($0["key"] as? String) ?? "": ($0["name"] as? String) ?? ""] } + .reduce(into: [String: String](), { $0[$1.key] = $1.value }) + let names = selectedIndexes? .compactMap { String($0) } - .compactMap { index in - champs?.first { $0["key"] as? String == index } - } - .compactMap { $0["name"] as? String } + .compactMap { champsDict?[$0] } ?? [] print(names) -// 코드는 깔끔해 졌으나 챔프를 탐색할 때 중복하여 탐색하게 되는 문제가 있다. -// 딕셔너리 배열이 아닌 딕셔너리로 탐색하면 비효율을 줄일 수 있을 것 같다. -// 딕셔너리 배열을 딕셔너리로 변경하려면 어떻게 해야 할까? -// 함수형으로 깔끔하게 변경하는 법을 좀 더 고민해야 겠다. +// flatMap과 reduce를 이용하여 딕셔너리 배열을 딕셔너리로 변경하였다. +// 그 결과 결과값을 바로 캐스팅하여 가져올 수 있게 되었다. +// 이전 코드 보단 한층 깔끔한 느낌이다. +// 다만 flatMap으로 튜플로 변경하는 부분의 코드가 가독성이 좋지 않고 지저분하다. +// 저것도 더 깔끔하게 변경할 수 있을지 고민해 봐야 겠다. From ea59b0db487bffe8b93dce197d8cd5afe2c23aee Mon Sep 17 00:00:00 2001 From: Seonghun Date: Wed, 13 Nov 2019 00:02:27 +0900 Subject: [PATCH 5/7] =?UTF-8?q?=E1=84=8F=E1=85=A9=E1=84=83=E1=85=B3=20?= =?UTF-8?q?=E1=84=85=E1=85=B5=E1=84=91=E1=85=A2=E1=86=A8=E1=84=90=E1=85=A9?= =?UTF-8?q?=E1=84=85=E1=85=B5=E1=86=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tutorial/Tutorial.playground/Contents.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Tutorial/Tutorial.playground/Contents.swift b/Tutorial/Tutorial.playground/Contents.swift index 78c94ac..0ddb47c 100644 --- a/Tutorial/Tutorial.playground/Contents.swift +++ b/Tutorial/Tutorial.playground/Contents.swift @@ -30,8 +30,9 @@ let selectedIndexes = try JSONSerialization.jsonObject(with: selectedIndexesData // TODO: selectedIndexes는 챔피언 목록(champs)의 key 번호 들이다. selectedIndexes에 명시된 순서대로 챔피언들의 이름(name)을 나열하라 let champsDict = champs? - .flatMap { [($0["key"] as? String) ?? "": ($0["name"] as? String) ?? ""] } - .reduce(into: [String: String](), { $0[$1.key] = $1.value }) + .flatMap { [$0["key"] as? String: $0["name"] as? String] } + // 옵셔널 값을 그대로 딕셔너리에 키값으로 넣었다. 지금은 오류가 없으나 추가적인 사이드 이팩트가 어떤게 있을까? + .reduce(into: [:]) { $0[$1.key] = $1.value } let names = selectedIndexes? .compactMap { String($0) } From b4d2e0b280b5ad45c2387cbe0fe741a48c49f918 Mon Sep 17 00:00:00 2001 From: Seonghun Date: Fri, 15 Nov 2019 19:17:08 +0900 Subject: [PATCH 6/7] =?UTF-8?q?=E1=84=8F=E1=85=A9=E1=84=83=E1=85=B3=20?= =?UTF-8?q?=E1=84=80=E1=85=A2=E1=84=89=E1=85=A5=E1=86=AB=20=E1=84=86?= =?UTF-8?q?=E1=85=B5=E1=86=BE=20=E1=84=8B=E1=85=B5=E1=86=A8=E1=84=86?= =?UTF-8?q?=E1=85=A7=E1=86=BC=E1=84=92=E1=85=A1=E1=86=B7=E1=84=89=E1=85=AE?= =?UTF-8?q?=20=E1=84=89=E1=85=A1=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=92?= =?UTF-8?q?=E1=85=A1=E1=84=8C=E1=85=B5=20=E1=84=8B=E1=85=A1=E1=86=AD?= =?UTF-8?q?=E1=84=83=E1=85=A9=E1=84=85=E1=85=A9=E1=86=A8=20=E1=84=89?= =?UTF-8?q?=E1=85=AE=E1=84=8C=E1=85=A5=E1=86=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tutorial/Tutorial.playground/Contents.swift | 41 +++++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/Tutorial/Tutorial.playground/Contents.swift b/Tutorial/Tutorial.playground/Contents.swift index 0ddb47c..5a1347d 100644 --- a/Tutorial/Tutorial.playground/Contents.swift +++ b/Tutorial/Tutorial.playground/Contents.swift @@ -24,25 +24,34 @@ let selectedIndexesFilePath = Bundle.main.path(forResource: "selectedIndexes", o let champsData = FileManager.default.contents(atPath: champsFilePath!) let selectedIndexesData = FileManager.default.contents(atPath: selectedIndexesFilePath!) -let champs = try JSONSerialization.jsonObject(with: champsData!, options: []) as? [[String: Any]] -let selectedIndexes = try JSONSerialization.jsonObject(with: selectedIndexesData!, options: []) as? [Int] - // TODO: selectedIndexes는 챔피언 목록(champs)의 key 번호 들이다. selectedIndexes에 명시된 순서대로 챔피언들의 이름(name)을 나열하라 -let champsDict = champs? - .flatMap { [$0["key"] as? String: $0["name"] as? String] } - // 옵셔널 값을 그대로 딕셔너리에 키값으로 넣었다. 지금은 오류가 없으나 추가적인 사이드 이팩트가 어떤게 있을까? - .reduce(into: [:]) { $0[$1.key] = $1.value } +struct Champ: Decodable { + let key: String + let name: String +} + +func merge(to dict: inout [String: String], from champ: Champ) { + dict[champ.key] = champ.name +} + +func champName(at key: Int) -> String? { + return champDict["\(key)"] +} + +let champs = try JSONDecoder().decode([Champ].self, from: champsData ?? Data()) +let selectedIndexes = try JSONDecoder().decode([Int].self, from: selectedIndexesData ?? Data()) + +let champDict = champs + .reduce(into: [:], merge) +// 처음엔 Champ의 init에서 Dictionary로 정보를 받아 처리해 주도록 하여 개선해 보았으나 고계함수의 활용과 거리가 멀어보여 JSONDecoder를 활용하여 개선하도록 수정하였다. -let names = selectedIndexes? - .compactMap { String($0) } - .compactMap { champsDict?[$0] } - ?? [] +let names = selectedIndexes + .compactMap(champName) +// Int를 String으로 변환해 주던 함수를 생략하였다. +// Int를 String으로 변환해 줄 뗀 옵셔널 타입이 아니라 compactMap을 사용할 필요가 없다. print(names) -// flatMap과 reduce를 이용하여 딕셔너리 배열을 딕셔너리로 변경하였다. -// 그 결과 결과값을 바로 캐스팅하여 가져올 수 있게 되었다. -// 이전 코드 보단 한층 깔끔한 느낌이다. -// 다만 flatMap으로 튜플로 변경하는 부분의 코드가 가독성이 좋지 않고 지저분하다. -// 저것도 더 깔끔하게 변경할 수 있을지 고민해 봐야 겠다. +// JSONDecoder를 활용하여 처리하도록 변경하였다. +// 그리고 익명함수를 안쓰고 적용할 수 있도록 변경해 보았다. From 06d377ed41692641bc74ca9aa2a4b7c98850ff80 Mon Sep 17 00:00:00 2001 From: Seonghun Date: Fri, 15 Nov 2019 21:19:01 +0900 Subject: [PATCH 7/7] =?UTF-8?q?=E1=84=8F=E1=85=A9=E1=84=83=E1=85=B3=20?= =?UTF-8?q?=E1=84=85=E1=85=B5=E1=84=91=E1=85=A2=E1=86=A8=E1=84=90=E1=85=A9?= =?UTF-8?q?=E1=84=85=E1=85=B5=E1=86=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tutorial/Tutorial.playground/Contents.swift | 27 +++++++++++---------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Tutorial/Tutorial.playground/Contents.swift b/Tutorial/Tutorial.playground/Contents.swift index 5a1347d..7532713 100644 --- a/Tutorial/Tutorial.playground/Contents.swift +++ b/Tutorial/Tutorial.playground/Contents.swift @@ -26,32 +26,33 @@ let selectedIndexesData = FileManager.default.contents(atPath: selectedIndexesFi // TODO: selectedIndexes는 챔피언 목록(champs)의 key 번호 들이다. selectedIndexes에 명시된 순서대로 챔피언들의 이름(name)을 나열하라 +typealias ChampHashMap = [String: String] + +extension ChampHashMap { + func name(at key: T) -> String? { + return self[String(key)] + } +} + struct Champ: Decodable { let key: String let name: String } -func merge(to dict: inout [String: String], from champ: Champ) { - dict[champ.key] = champ.name -} - -func champName(at key: Int) -> String? { - return champDict["\(key)"] +func merge(to hashMap: inout ChampHashMap, from champ: Champ) { + hashMap[champ.key] = champ.name } let champs = try JSONDecoder().decode([Champ].self, from: champsData ?? Data()) let selectedIndexes = try JSONDecoder().decode([Int].self, from: selectedIndexesData ?? Data()) -let champDict = champs +let champHashMap = champs .reduce(into: [:], merge) -// 처음엔 Champ의 init에서 Dictionary로 정보를 받아 처리해 주도록 하여 개선해 보았으나 고계함수의 활용과 거리가 멀어보여 JSONDecoder를 활용하여 개선하도록 수정하였다. let names = selectedIndexes - .compactMap(champName) -// Int를 String으로 변환해 주던 함수를 생략하였다. -// Int를 String으로 변환해 줄 뗀 옵셔널 타입이 아니라 compactMap을 사용할 필요가 없다. + .compactMap(champHashMap.name) print(names) -// JSONDecoder를 활용하여 처리하도록 변경하였다. -// 그리고 익명함수를 안쓰고 적용할 수 있도록 변경해 보았다. +// 함수 내부에서 함수 밖의 프로퍼티에 접근 하는 것은 위험하다고 생각되어 ChampHashMap 타입을 정의하고 ChampHashMap을 확장하여 이름을 리턴하도록 변경하였다. +// hashMap이 dictionary보다 의도가 잘 드러날 거라 기대하여 변경하였다.