들어온 데이터를 같은 날짜별로 분리해야할 일이 생겨 오랜만에 포스팅에 좋겠다 싶어서 남긴다.

스위프트의 Dictionary 는 무려 이러한 분할을 조건만 명시해주면 알아서 해준다.

이걸 어떻게 구현해야할지 막막해지며 포문안에 키값을 추출하며 분리해 나가야하나 싶었는데

그냥 알아서 제공해줘서 매우 기쁘다.

공식 문서는 아래와 같다.

https://developer.apple.com/documentation/swift/dictionary/3127163-init

 

Apple Developer Documentation

 

developer.apple.com

 

생성자 형태.

init<S>(grouping values: S, by keyForValue: (S.Element) throws -> Key) 
rethrows where Value == [S.Element], S : Sequence

 

 

형태는 S를 줘서 키값을 리턴해주면된다.

바로 코드로 테스트해보면

데이터 형태는 TestItem, 테스트 하기 편하게 id와 updateAt 만 주고

struct TestItem: Codable {
    let id: Int
    let updatedAt: String?
}

 

받은 데이터는 아래와같은거로 가정 16,17은 업데이트 값이 이상하게 들어간 경우를 테스트

let testArray: [TestItem] = [
    .init(id: 0, updatedAt: "2022-04-22T13:18:08.000Z"),
    .init(id: 1, updatedAt: "2022-04-22T13:18:08.000Z"),
    .init(id: 2, updatedAt: "2022-04-08T13:18:08.000Z"),
    .init(id: 3, updatedAt: "2022-04-07T13:18:08.000Z"),
    .init(id: 4, updatedAt: "2022-04-07T13:18:08.000Z"),
    .init(id: 5, updatedAt: "2022-04-05T13:18:08.000Z"),
    .init(id: 6, updatedAt: "2022-03-20T13:18:08.000Z"),
    .init(id: 7, updatedAt: "2022-03-17T13:18:08.000Z"),
    .init(id: 8, updatedAt: "2022-03-17T13:18:08.000Z"),
    .init(id: 9, updatedAt: "2022-03-16T13:18:08.000Z"),
    .init(id: 10, updatedAt: "2022-02-08T13:18:08.000Z"),
    .init(id: 11, updatedAt: "2022-01-08T13:18:08.000Z"),
    .init(id: 12, updatedAt: "2021-01-08T13:18:08.000Z"),
    .init(id: 13, updatedAt: "2021-04-08T13:18:08.000Z"),
    .init(id: 14, updatedAt: "2021-04-30T13:18:08.000Z"),
    .init(id: 15, updatedAt: "2020-04-01T13:18:08.000Z"),
    .init(id: 16, updatedAt: "2020-04-0113:18:08.000Z"),
    .init(id: 17, updatedAt: nil),
]

 

이제 그룹핑하고 찍어보자면

updatedAt이 제대로 입력되지 않은 녀석은 blank라는 키로 따로 뺏다.

여기선 검사를 안했지만 정규식패턴으로 updatedAt을 검사하는 과정을 넣는게 좋을듯 보임

let groupedDict: [String: [TestItem]] = Dictionary(grouping: testArray)
{ item in
    guard let updatedAt: String = item.updatedAt else { return "blank"}
    let split = updatedAt.split(separator: "T")
    guard split.count == 2 else { return "blank" }
    let dateString: String = String(split[0])
    return dateString
}

for key in groupedDict.keys {
    print("key : \(key)")
    let values: [TestItem] = groupedDict[key]!
    for value in values {
        print("id: \(value.id), updatedAt: \(value.updatedAt ?? "")")
    }
    print("")
    print("")
}

 

출력:

key : 2021-01-08
id: 12, updatedAt: 2021-01-08T13:18:08.000Z


key : 2022-04-07
id: 3, updatedAt: 2022-04-07T13:18:08.000Z
id: 4, updatedAt: 2022-04-07T13:18:08.000Z


key : 2020-04-01
id: 15, updatedAt: 2020-04-01T13:18:08.000Z


key : blank
id: 16, updatedAt: 2020-04-0113:18:08.000Z
id: 17, updatedAt: 


key : 2022-03-20
id: 6, updatedAt: 2022-03-20T13:18:08.000Z


key : 2022-02-08
id: 10, updatedAt: 2022-02-08T13:18:08.000Z


key : 2022-01-08
id: 11, updatedAt: 2022-01-08T13:18:08.000Z


key : 2022-03-17
id: 7, updatedAt: 2022-03-17T13:18:08.000Z
id: 8, updatedAt: 2022-03-17T13:18:08.000Z


key : 2022-04-08
id: 2, updatedAt: 2022-04-08T13:18:08.000Z


key : 2022-03-16
id: 9, updatedAt: 2022-03-16T13:18:08.000Z


key : 2022-04-05
id: 5, updatedAt: 2022-04-05T13:18:08.000Z


key : 2022-04-22
id: 0, updatedAt: 2022-04-22T13:18:08.000Z
id: 1, updatedAt: 2022-04-22T13:18:08.000Z


key : 2021-04-30
id: 14, updatedAt: 2021-04-30T13:18:08.000Z


key : 2021-04-08
id: 13, updatedAt: 2021-04-08T13:18:08.000Z

딕셔너리는 순서를 지키지 않기에 

만약 데이터로 가공해야한다면 키값에 대한 정렬이 필요해보인다.

+ Recent posts