87

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"]
0

9 Answers 9

136

@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) }
Sign up to request clarification or add additional context in comments.

7 Comments

loving this method
good answer! but do you know how to write this on obj-c ? please help me out :) thanks
If the elements are 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.
To make it work, your object also has to conform to the Equatable protocol. If it doesn't you get this weird error in Swift 4.0 saying: Missing argument label 'where:' in call in the contains function inside the filter.
@c1pherB1t yes, you can add the where:in the contains i.e. array1 = array1.filter({ item in !array2.contains(where: { $0.id == item.id }) })
|
86

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"]

6 Comments

Can you subtract an array from a set? Wouldn't that need to be array1 = Array(Set(array1).subtract(Set(array2))) (Converting Array2 to a set before subtracting it from array1?)
@DuncanC: the subtract method (as well as many other Set methods) takes a SequenceType argument, so yes, you can pass an array.
I use: /* Swift 3.x */ func - <Element: Hashable>(lhs: [Element], rhs: [Element]) -> [Element] { return Array(Set<Element>(lhs).subtracting(Set<Element>(rhs))) }
That's really nice - it also seems to respect the original order - is that always guaranteed?
The order is not guaranteed: > An unordered collection of unique elements. developer.apple.com/documentation/swift/set
|
9

Remove elements using indexes array:

  1. 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"]
    
  2. 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

  1. 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]
    
  2. 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"]
    

Comments

4

You can create sets and then use the subtract method

let setA = Set(arr1)
let setB = Set(arr2)
setA.subtract(setB)

2 Comments

intersect show the elements in common , i want to delete the elements in common and get the others in another array
I update the code, for that you need to use subtract
4

Here is an extension with @jrc answer:

extension Array where Element: Equatable {
    func subtracting(_ array: Array<Element>) -> Array<Element> {
        self.filter { !array.contains($0) }
    }
}

1 Comment

Nice approach but if you have a million entries this is n^2
2

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 :)

1 Comment

That’s not very efficient. Just do this: [[array1 mutableCopy] removeObjectsInArray:array2]
1

An extended version of the answer by Shai Balassiano:

extension Array where Element: Equatable {
  func subtracting(_ array: [Element]) -> [Element] {
      self.filter { !array.contains($0) }
  }

  mutating func remove(_ array: [Element]) {
      self = self.subtracting(array)
  }
}

Comments

1

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"]

Comments

0

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]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.