Skip to content

Instantly share code, notes, and snippets.

@davidbjames
Last active October 15, 2017 08:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidbjames/96da7bbd720600fddd684877afb670b4 to your computer and use it in GitHub Desktop.
Save davidbjames/96da7bbd720600fddd684877afb670b4 to your computer and use it in GitHub Desktop.
Equatable Set-like functionality on Array.
/// Set-like functionality on Arrays Equatable elements.
/// Performance on these is O(n)
public extension Array where Element : Equatable {
func removingDuplicates() -> Array<Iterator.Element> {
var newArray = [Element]()
for element in self {
newArray.formUnion(element)
}
return newArray
}
/// Insert an element if it does not already exist in the array
/// and return a new array.
/// Example: [a,b,c].insert(a) --> [a,b,c]
func insert(_ element:Element) -> Array<Element> {
var newArray = self
newArray.formUnion(element)
return newArray
}
/// Insert or replace an element regardless.
func update(with element:Element) -> Array<Element> {
var newArray = self
if let index = newArray.index(of: element) {
newArray[index] = element
} else {
newArray.append(element)
}
return newArray
}
/// Append an array of elements if they do not already exist in the array
/// and return a new array.
/// Example: [a,b,c].union([a,d]) --> [a,b,c,d]
func union(_ elements:[Element]) -> Array<Element> {
var newArray = self
newArray.formUnion(elements)
return newArray
}
/// Append an element if it does not already exist in the array
/// Example: [a,b,c].formUnion(a) --> [a,b,c]
mutating func formUnion(_ element:Element) {
if doesNotContain(element) {
append(element)
}
}
/// Append an array of elements if they do not already exist in the array
/// Example: [a,b,c].formUnion([a,d]) --> [a,b,c,d]
mutating func formUnion(_ elements:[Element]) {
for element in elements {
formUnion(element)
}
}
/// Return array including elements shared in self and provided array.
/// Example: [a,b,c].intersection([b,c,d]) --> [b,c]
func intersection(_ elements:[Element]) -> Array<Element> {
var newArray = self
newArray.formIntersection(elements)
return newArray
}
/// Mutate array to only include elements shared in self and provided array.
/// Example: [a,b,b,c].formIntersection([b,c,d]) --> [b,b,c]
mutating func formIntersection(_ rElements:[Element]) {
var result = Array<Element>()
for lElement in self {
if rElements.contains(lElement) { // && result.doesNotContain(lElement)
result.append(lElement)
}
}
self.removeAll()
self.append(contentsOf: result)
}
/// Return array including elements that are not shared
/// in self and provided array.
/// a.k.a. exclusiveOr / symmetricDifference
/// Example: [a,b,c,a].difference([b,b,c,d]) --> [a,d]
func difference(_ elements:[Element]) -> Array<Element> {
var newArray = self
newArray.formDifference(elements)
return newArray
}
/// Mutate array to only include elements that are not shared
/// in self and provided array.
/// a.k.a. exclusiveOr / symmetricDifference
/// As far as ordering is concerned, elements on the left side
/// come out first and elements on the right side come out last.
/// Example: [a,b,c,a].formDifference([b,b,c,d]) --> [a,a,d]
mutating func formDifference(_ rElements:[Element]) {
var result = Array<Element>()
for lElement in self {
if rElements.doesNotContain(lElement) { // && result.doesNotContain(lElement)
result.append(lElement)
}
}
for rElement in rElements {
if self.doesNotContain(rElement) { // && result.doesNotContain(rElement)
result.append(rElement)
}
}
self.removeAll()
self.append(contentsOf: result)
}
/// Return array with elements in provided array "subtracted"
/// from original array.
func subtract(_ elements:[Element]) -> Array<Element> {
var newArray = self
newArray.formSubtraction(elements)
return newArray
}
/// Mutate array subtracting provided array from the original array.
/// [a,a,b,c].formSubtraction([b,c,d]) --> [a,a]
/// also: [a,a,b,c].formSubtraction([a,b,c,d]) --> []
mutating func formSubtraction(_ rElements:[Element]) {
var result = [Element]()
for lElement in self {
if rElements.doesNotContain(lElement) {
result.append(lElement)
}
}
self.removeAll()
self.append(contentsOf: result)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment