I have two arrays
var array1 = new Array ["a", "b", "c", "d", "e"]
var array2 = new Array ["a", "c", "d"]
I want to remove elements of array2 from array1
Result ["b", "e"]
@Antonio's solution is more performant, but this preserves ordering, if that's important:
var array1 = ["a", "b", "c", "d", "e"]
let array2 = ["a", "c", "d"]
array1 = array1.filter { !array2.contains($0) }
Hashable like they are in this case, it might be more performant to convert array2 into a Set first; this would still preserve the order as array1 remains an array, but you can perform fast lookups on the search collection.where:in the contains i.e. array1 = array1.filter({ item in !array2.contains(where: { $0.id == item.id }) })The easiest way is to convert both arrays to sets, subtract the second from the first, convert to the result to an array and assign it back to array1:
array1 = Array(Set(array1).subtracting(array2))
Note that your code is not valid Swift - you can use type inference to declare and initialize both arrays as follows:
var array1 = ["a", "b", "c", "d", "e"]
var array2 = ["a", "c", "d"]
array1 = Array(Set(array1).subtract(Set(array2))) (Converting Array2 to a set before subtracting it from array1?)subtract method (as well as many other Set methods) takes a SequenceType argument, so yes, you can pass an array./* Swift 3.x */ func - <Element: Hashable>(lhs: [Element], rhs: [Element]) -> [Element] { return Array(Set<Element>(lhs).subtracting(Set<Element>(rhs))) }Remove elements using indexes array:
Array of Strings and indexes
let animals = ["cats", "dogs", "chimps", "moose", "squarrel", "cow"]
let indexAnimals = [0, 3, 4]
let arrayRemainingAnimals = animals
.enumerated()
.filter { !indexAnimals.contains($0.offset) }
.map { $0.element }
print(arrayRemainingAnimals)
//result - ["dogs", "chimps", "cow"]
Array of Integers and indexes
var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
let indexesToRemove = [3, 5, 8, 12]
numbers = numbers
.enumerated()
.filter { !indexesToRemove.contains($0.offset) }
.map { $0.element }
print(numbers)
//result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
Remove elements using element value of another array
Arrays of integers
let arrayResult = numbers.filter { element in
return !indexesToRemove.contains(element)
}
print(arrayResult)
//result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
Arrays of strings
let arrayLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
let arrayRemoveLetters = ["a", "e", "g", "h"]
let arrayRemainingLetters = arrayLetters.filter {
!arrayRemoveLetters.contains($0)
}
print(arrayRemainingLetters)
//result - ["b", "c", "d", "f", "i"]
You can create sets and then use the subtract method
let setA = Set(arr1)
let setB = Set(arr2)
setA.subtract(setB)
Here is an extension with @jrc answer:
extension Array where Element: Equatable {
func subtracting(_ array: Array<Element>) -> Array<Element> {
self.filter { !array.contains($0) }
}
}
out of scope but it would help me if it had been here. removing subArray from array in OBJECTIVE-C
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"not (self IN %@)", subArrayToBeDeleted];
NSArray* finalArray = [initialArray filteredArrayUsingPredicate:predicate];
hope it will ever help someone :)
[[array1 mutableCopy] removeObjectsInArray:array2]Here is one more solution by defining your own PredicateSet.
struct PredicateSet<A> {
let contains: (A) -> Bool
}
let animals = ["Cow", "Bulldog", "Labrador"]
let dogs = ["Bulldog", "Labrador"]
let notDogs = PredicateSet { !dogs.contains($0) }
print(animals.filter(notDogs.contains)) // ["Cow"]
If there are 2 arrays which contains duplicated element, and you need just a simple subtraction, You can use this code. This works for String type as well.
extension Array where Element: Equatable {
func subtracting(_ array: Array<Element>) -> Array<Element> {
var result: Array<Element> = []
var toSub = array
for i in self {
if let index = toSub.firstIndex(of: i) {
toSub.remove(at: index)
continue
}
else {
result.append(i)
}
}
return result
}
}
let first = [1, 1, 2, 3, 3, 5, 6, 7, 7]
let second = [2, 2, 3, 4, 4, 5, 5, 6]
let result = first.subtracting(second)
//print result
//[1, 1, 3, 7, 7]