Swift/개념 & 응용

[Swift] difference(from:)와 applying(_:)

유정주 2024. 4. 20. 17:10
반응형

difference(from:)

difference(from:)은 두 개의 Collection 차이를 쉽게 구할 수 있는 메서드입니다.

A와 B를 비교했을 때 무엇이 추가로 있고, 무엇이 없는지 알 수 있습니다.

(A collection of insertions and removals that describe the difference between two ordered collection states.)

 

사용법도 간단합니다.

let arr1 = [1, 2, 3, 4]
let arr2 = [1, 3, 4, 5]

let diff = arr2.difference(from: arr1)

 

diff를 출력해 보면 arr1이 arr2가 되기 위해 무엇을 추가하고, 무엇을 빼야 하는지 알 수 있습니다.

"CollectionDifference<Int>(insertions: [Swift.CollectionDifference<Swift.Int>.Change.insert(offset: 3, element: 5, associatedWith: nil)], removals: [Swift.CollectionDifference<Swift.Int>.Change.remove(offset: 1, element: 2, associatedWith: nil)])\n"

CollectionDifference<ChangeElement> 타입으로 반환되기 때문에 위와 같은 출력 값이 표시됩니다.

 

위 출력에서 표시되고 있는 insertions와 removals는 CollectionDifference.Change 타입으로

insert와 remove case가 있는 enum입니다.

 

CollectionDifference 구조체 안에서 어떤 offset의 어떤 element가 추가되어야 하고, 삭제되어야 하는지 알려줍니다.

 

arr1과 arr2를 비교한 diff 출력 값을 예로 들면,

  • insertions: 3번 offset에 5를 추가해야 한다.
  • removals: 1번 offset의 2를 제거해야 한다.

를 알 수 있습니다.

 

diff의 각 case를 출력하면

for item in diff {
    switch item {
    case .insert(let offset, let element, _):
        print("\(offset)번 offset에 \(element)가 추가되었습니다.")
    case .remove(let offset, let element, _):
        print("\(offset)번 offset의 \(element)가 삭제되었습니다.")
    }
}
3번 offset에 5가 추가되었습니다.
1번 offset의 2가 삭제되었습니다.

간편하게 정보를 알 수 있습니다.

 

 

applying

applying 메서드를 사용하면 CollectionDifference로 구한 차이값을 한 번에 적용할 수 있습니다.

let arr3 = arr1.applying(diff)
print(arr3)
// arr2와 똑같아짐

 

 

활용법

TableView나 CollectionView의 reload를 효율적으로 처리할 수 있습니다.

difference(from:)의 시간 복잡도는 최악의 경우 O(NM)이고, 공통 값이 많을수록 빠릅니다.

따라서 difference 값으로 차이가 있는 부분만 업데이트하면 매번 reloadData를 호출해서 모든 데이터를 업데이트하는 것보다 효율적입니다.

 

 

DifferenceKit

DifferenceKit은 O(N)으로 동일한 작업을 처리할 수 있는 라이브러리입니다.

최근 당근이 공개한 KarrotListKit을 통해 알게 되었는데요.

유일하게 존재하는 의존 라이브러리라 궁금해서 찾아보게 되었습니다.

 

List 업데이트를 O(NM)에서 O(N)으로 처리할 수 있으니 좋은 적용이라고 생각했습니다.

복잡한 알고리즘이 들어가는데 이런건 이미 잘 구현된 라이브러리를 쓰는 것도 좋죠 👍

덕분에 좋은 라이브러리를 알게 되었습니다.

 

아직 써보진 않아서 직접 써보게 됐을 때 따로 포스팅을 해보겠습니다.

 

감사합니다.

 

참고

https://developer.apple.com/documentation/swift/array/difference(from:)

https://developer.apple.com/documentation/swift/collectiondifference/change

https://developer.apple.com/documentation/swift/collectiondifference

https://developer.apple.com/documentation/swift/string/applying(_:)

https://github.com/ra1028/DifferenceKit?tab=readme-ov-file


아직은 초보 개발자입니다.

더 효율적인 코드 훈수 환영합니다!

공감 댓글 부탁드립니다.

 

 

반응형