Skip to content

Instantly share code, notes, and snippets.

@atierian
Created July 13, 2021 12:09
Show Gist options
  • Save atierian/bcc0102b61cf68e14300e4cb0493b097 to your computer and use it in GitHub Desktop.
Save atierian/bcc0102b61cf68e14300e4cb0493b097 to your computer and use it in GitHub Desktop.
Remove duplicates determined KeyPath
import UIKit
import PlaygroundSupport
import XCTest
extension Array {
/// Remove duplicates based on `KeyPath`
/// - Parameter keyPath: Property to determine uniqueness
/// - Returns: `Array` of unique `Elements` based on `keyPath` argument
/// - Complexity Time: O(n) / Space: O(n)
func removingDuplicates<T: Hashable>(by keyPath: KeyPath<Element, T>) -> Self {
var seen = Set<T>()
return compactMap {
guard !seen.contains($0[keyPath: keyPath]) else { return nil }
seen.insert($0[keyPath: keyPath])
return $0
}
}
/// Remove duplicates based on `KeyPath`
/// - Parameter keyPath: Property to determine uniqueness
/// - Complexity Time: O(n) / Space: O(n)
mutating func removeDuplicates<T: Hashable>(by keyPath: KeyPath<Element, T>) {
self = removingDuplicates(by: keyPath)
}
}
class RemoveDuplicatesByKeyPathTestCase: XCTestCase {
struct Foo {
let bar: Int
}
var array = Array(repeating: Foo(bar: 1), count: 5)
override func setUp() {
array.append(contentsOf: (2...10).map(Foo.init))
}
func testRemovingDuplicates() {
let uniqueByKeyPathArray = array.removingDuplicates(by: \.bar)
XCTAssertEqual(uniqueByKeyPathArray.map(\.bar), (1...10).map { $0 })
}
func testRemoveDuplicates() {
array.removeDuplicates(by: \.bar)
XCTAssertEqual(array.map(\.bar), (1...10).map { $0 })
}
}
RemoveDuplicatesByKeyPathTestCase.defaultTestSuite.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment