Removing objects from an array based on another array

前端 未结 9 1453
南方客
南方客 2021-02-05 01:14

I have two arrays like this:

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

相关标签:
9条回答
  • 2021-02-05 01:18

    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/4.x
    func - <Element: Hashable>(lhs: [Element], rhs: [Element]) -> [Element]
    {
        return Array(Set<Element>(lhs).subtracting(Set<Element>(rhs)))
    }
    
    0 讨论(0)
  • 2021-02-05 01:24

    For smaller arrays I use:

    /* poormans sub for Arrays */
    
    extension Array where Element: Equatable {
    
        static func -=(lhs: inout Array, rhs: Array) {
    
            rhs.forEach {
                if let indexOfhit = lhs.firstIndex(of: $0) {
                    lhs.remove(at: indexOfhit)
                }
            }
        }
    
        static func -(lhs: Array, rhs: Array) -> Array {
    
            return lhs.filter { return !rhs.contains($0) }
        }
    }
    
    0 讨论(0)
  • 2021-02-05 01:26

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

     arrayA = arrayA.filter { !arrayB.contains($0) }
    
    0 讨论(0)
  • 2021-02-05 01:27

    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
    }
    
    0 讨论(0)
  • 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) }
    
    0 讨论(0)
  • 2021-02-05 01:35

    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)
        }
    }
    
    0 讨论(0)
提交回复
热议问题