How to determine if one array contains all elements of another array in Swift?

后端 未结 12 1108
梦如初夏
梦如初夏 2020-12-13 17:47

I have 2 arrays:

var list:Array = [1,2,3,4,5]
var findList:Array = [1,3,5]

I want to determine if list A

相关标签:
12条回答
  • 2020-12-13 18:08

    This is Maxim Shoustin's answer updated for Swift 3:

    func arrayContainsArray<S : Sequence>
        (src:S, lookFor:S) -> Bool where S.Iterator.Element : Equatable{
    
        for v:S.Iterator.Element in lookFor{
            if src.contains(v) == false{
                return false
            }
        }
        return true
    }
    
    0 讨论(0)
  • 2020-12-13 18:09

    Instead of iterating through arrays and doing filtering yourself, you can use NSSet to do all the work for you.

    var list:Array<Int> = [1,2,3,4,5]
    var findList:Array<Int> = [1,3,5]
    
    let listSet = NSSet(array: list)
    let findListSet = NSSet(array: findList)
    
    let allElemtsEqual = findListSet.isSubsetOfSet(otherSet: listSet)
    

    NSSet is a lot faster than arrays at checking if it contains any object. In fact it's what it's designed for.

    Edit: Using Swift's built-in Set.

    let list = [1,2,3,4,5]
    let findList = [1,3,5]
    let listSet = Set(list)
    let findListSet = Set(findList)
    //**Swift 4.2 and Above**
    let allElemsContained = findListSet.isSubset(of: listSet)
    
    //below versions
    //let allElemsContained = findListSet.isSubsetOf(listSet)
    
    0 讨论(0)
  • 2020-12-13 18:11

    You can use the filter method to return all elements of findList which are not in list:

    let notFoundList = findList.filter( { contains(list, $0) == false } )
    

    then check if the length of the returned array is zero:

    let contained = notFoundList.count == 0
    

    Note that his solution traverses the entire findList array, so it doesn't stop as soon as a non contained element is found. It should be used if you also want to know which elements are not contained.

    If you just need a boolean stating whether all elements are contained or not, then the solution provided by Maxim Shoustin is more efficient.

    0 讨论(0)
  • 2020-12-13 18:13

    allSatisfy seems to be what you want, assuming you can't conform your elements to Hashable and use the set intersection approach others have mentioned:

    let containsAll = subArray.allSatisfy(largerArray.contains)
    
    0 讨论(0)
  • 2020-12-13 18:18

    In Swift 3 or Swift 4 you can write this:

    extension Array where Element: Equatable {
        func contains(array: [Element]) -> Bool {
            for item in array {
                if !self.contains(item) { return false }
            }
            return true
        }
    }
    

    You can see the contains method here

    This is just a simple extension that check if the array that you give is in the current array (self)

    0 讨论(0)
  • 2020-12-13 18:20

    Consider following generic method:

    func arrayContainsArray<S : SequenceType where S.Generator.Element : Equatable>
          (src:S, lookFor:S) -> Bool{
    
        for v:S.Generator.Element in lookFor{
          if contains(src, v) == false{
            return false
          }
        }
       return true
    }
    

    The advantage - method stops after 1st fail and do not continue over findList


    Tests

    var listAsInt:Array<Int> = [1,2,3,4,5]
    var findListAsInt:Array<Int> = [1,3,5]
    var result = arrayContainsArray(listAsInt, findListAsInt) // true
    

    listAsInt:Array<Int> = [1,2,3,4,5]
    findListAsInt:Array<Int> = [1,3,5,7,8,9]
    result = arrayContainsArray(listAsInt, findListAsInt) // false
    

    var listOfStr:Array<String> = ["aaa","bbb","ccc","ffffd","eee"]
    var findListOfStr:Array<String> = ["bbb","ccc","eee"]
    result = arrayContainsArray(listOfStr, findListOfStr) // true
    

    listOfStr:Array<String> = ["aaa","bbb","ccc","ffffd","eee"]
    findListOfStr:Array<String> = ["bbb","ccc","eee","sss","fff","ggg"]
    result = arrayContainsArray(listOfStr, findListOfStr) // false
    

    (tested on Beta7)

    0 讨论(0)
提交回复
热议问题