Home » Swift » Removing objects from an array based on another array in Swift

Removing objects from an array based on another array in Swift

Posted by: admin November 30, 2017 Leave a comment

Questions:

I have two arrays like this:

var arrayA = ["Mike", "James", "Stacey", "Steve"]
var arrayB = ["Steve", "Gemma", "James", "Lucy"]

As you can see, James and Steve match and I want to be able to remove them from arrayA. How would I write this?

Answers:

Like this:

var arrayA = ["Mike", "James", "Stacey", "Steve"]
var arrayB = ["Steve", "Gemma", "James", "Lucy"]
for word in arrayB {
    if let ix = find(arrayA, word) {
        arrayA.removeAtIndex(ix)
    }
}
// now arrayA is ["Mike", "Stacey"]

Questions:
Answers:

The easiest way is by using the new Set container (added in Swift 1.2 / Xcode 6.3):

var setA = Set(arrayA)
var setB = Set(arrayB)

// Return a set with all values contained in both A and B
let intersection = setA.intersect(setB) 

// Return a set with all values in A which are not contained in B
let diff = setA.subtract(setB)

If you want to reassign the resulting set to arrayA, simply create a new instance using the copy constructor and assign it to arrayA:

arrayA = Array(intersection)

The downside is that you have to create 2 new data sets.
Note that intersect doesn’t mutate the instance it is invoked in, it just returns a new set.

There are similar methods to add, subtract, etc., you can take a look at them

Questions:
Answers:

@francesco-vadicamo’s answer in Swift 2/3/4+

 arrayA = arrayA.filter { !arrayB.contains($0) }

Demo here.

Questions:
Answers:

matt and freytag’s solutions are the ONLY ones that account for duplicates and should be receiving more +1s than the other answers.

Here is an updated version of matt’s answer for Swift 3.0:

var arrayA = ["Mike", "James", "Stacey", "Steve"]
var arrayB = ["Steve", "Gemma", "James", "Lucy"]
for word in arrayB {
    if let ix = arrayA.index(of: word) {
        arrayA.remove(at: ix)
    }
}

Questions:
Answers:

I agree with Antonio’s answer, however for small array subtractions you can also use a filter closure like this:

let res = arrayA.filter { !contains(arrayB, $0) }

Questions:
Answers:

This can also be implemented as a minus func:

func -<T:RangeReplaceableCollectionType where T.Generator.Element:Equatable>( lhs:T, rhs:T ) -> T {

    var lhs = lhs
    for element in rhs {
        if let index = lhs.indexOf(element) { lhs.removeAtIndex(index) }
    }

    return lhs
}

Now you can use

arrayA - arrayB

Questions:
Answers:

Using the Array → Set → Array method mentioned by Antonio, and with the convenience of an operator, as freytag pointed out, I’ve been very satisfied using this:

// Swift 3.x
func - <Element: Hashable>(lhs: [Element], rhs: [Element]) -> [Element]
{
    return Array(Set<Element>(lhs).subtracting(Set<Element>(rhs)))
}

Questions:
Answers:

Here are same operations with array of integers
Swift 3

var array1 = [1, 2, 3, 4, 5, 6]

var array2 = [1,5]

var arrayResult = array1.enumerated()
    .filter { !array2.contains($0.0 + 1) }
    .map { $0.1 }

print(arrayResult)
[2, 3, 4, 6]

Another ways to achieve the same result:

1. Use filter

let arrayResult = array1.filter { element in
    return !array2.contains(element)
}

2. Use Sort

array2.sorted(by: >).forEach { if $0 < self.array1.count { self.array1.remove(at: $0) } }