Skip to content

Instantly share code, notes, and snippets.

@NachoSoto
Created December 27, 2017 01:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NachoSoto/b6b9608e400802103d38ece4a4204885 to your computer and use it in GitHub Desktop.
Save NachoSoto/b6b9608e400802103d38ece4a4204885 to your computer and use it in GitHub Desktop.
Example of how to extract unique elements from a sequence in Swift
import Foundation
extension Sequence {
// Extension on Sequence allows us to use this method on Arrays, Maps, Sets, etc.
func uniqueElements<Index: Hashable>(for indexer: (Element) -> Index) -> [Element] {
// Keep track of what we've already seen in a Set,
// which allows us to query for elements efficiently.
var seenElements: Set<Index> = []
var result: [Element] = []
// Simple implementation looping through the sequence.
// That means that the computational complexity of this is O(n log n).
// In other words, only a little bit worse than linear complexity.
//
// This could be done in other ways (using NSOrderedSet for example),
// but this is just for illustration purposes (see https://twitter.com/olearydan/status/945702613596721152).
for element in self {
let index = indexer(element)
guard !seenElements.contains(index) else {
continue
}
seenElements.insert(index)
result.append(element)
}
return result
}
}
// If the elements of a sequence are already Hashable, we can define a shorthand.
extension Sequence where Element: Hashable {
var uniqueElements: [Element] {
return self.uniqueElements { $0 }
}
}
/// --------------- Examples ------------
struct Person {
let name: String
let id: Int
}
let numbers = [1, 2, 3, 1, 2, 3, 4, 1, 2]
numbers.uniqueElements
let people: [Person] = [
Person(name: "Nacho", id: 1),
Person(name: "Dan", id: 2),
Person(name: "Nacho", id: 3),
Person(name: "Steve", id: 4)
]
// We can also "index" them by a different property
people.uniqueElements { $0.name }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment