Removing objects from an array based on another ar

2020-05-24 19:35发布

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?

9条回答
再贱就再见
2楼-- · 2020-05-24 20:00

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"]
    
查看更多
疯言疯语
3楼-- · 2020-05-24 20:03

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) }
查看更多
可以哭但决不认输i
4楼-- · 2020-05-24 20:06

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"]
查看更多
SAY GOODBYE
5楼-- · 2020-05-24 20:07

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

查看更多
啃猪蹄的小仙女
6楼-- · 2020-05-24 20:09

Original answer

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

Updated implementation for Swift 5

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

    var lhs = lhs
    for element in rhs {
        if let index = lhs.firstIndex(of: element) { lhs.remove(at: index) }
    }

    return lhs
}
查看更多
狗以群分
7楼-- · 2020-05-24 20:16

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

 arrayA = arrayA.filter { !arrayB.contains($0) }
查看更多
登录 后发表回答