我有2个数组:
var list:Array<Int> = [1,2,3,4,5]
var findList:Array<Int> = [1,3,5]
Run Code Online (Sandbox Code Playgroud)
我想确定list
Array是否包含所有findList
元素.
顺便说一下,元素也可以String
是其他类型.
怎么做?
我知道Swift提供的contains
方法适用于一个项目.
ork*_*den 53
您可以使用NSSet
为您完成所有工作,而不是遍历数组并自行过滤.
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)
Run Code Online (Sandbox Code Playgroud)
NSSet
在检查它是否包含任何对象时比数组快很多.事实上,它就是它的设计目标.
编辑:使用Swift的内置功能Set
.
let list = [1,2,3,4,5]
let findList = [1,3,5]
let listSet = Set(list)
let findListSet = Set(findList)
let allElemsContained = findListSet.isSubsetOf(listSet)
Run Code Online (Sandbox Code Playgroud)
考虑以下通用方法:
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
}
Run Code Online (Sandbox Code Playgroud)
优势 - 方法在第一次失败后停止,不要继续 findList
测试
var listAsInt:Array<Int> = [1,2,3,4,5]
var findListAsInt:Array<Int> = [1,3,5]
var result = arrayContainsArray(listAsInt, findListAsInt) // true
Run Code Online (Sandbox Code Playgroud)
listAsInt:Array<Int> = [1,2,3,4,5]
findListAsInt:Array<Int> = [1,3,5,7,8,9]
result = arrayContainsArray(listAsInt, findListAsInt) // false
Run Code Online (Sandbox Code Playgroud)
var listOfStr:Array<String> = ["aaa","bbb","ccc","ddd","eee"]
var findListOfStr:Array<String> = ["bbb","ccc","eee"]
result = arrayContainsArray(listOfStr, findListOfStr) // true
Run Code Online (Sandbox Code Playgroud)
listOfStr:Array<String> = ["aaa","bbb","ccc","ddd","eee"]
findListOfStr:Array<String> = ["bbb","ccc","eee","sss","fff","ggg"]
result = arrayContainsArray(listOfStr, findListOfStr) // false
Run Code Online (Sandbox Code Playgroud)
(在Beta7上测试过)
您可以使用该filter
方法返回findList
其中不包含的所有元素list
:
let notFoundList = findList.filter( { contains(list, $0) == false } )
Run Code Online (Sandbox Code Playgroud)
然后检查返回数组的长度是否为零:
let contained = notFoundList.count == 0
Run Code Online (Sandbox Code Playgroud)
请注意,他的解决方案遍历整个findList
数组,因此只要找到不包含的元素,它就不会停止.如果您还想知道哪些元素未包含,则应该使用它.
如果您只需要一个布尔表明是否包含所有元素,那么Maxim Shoustin提供的解决方案更有效.
在Swift 3或Swift 4中你可以这样写:
extension Array where Element: Equatable {
func contains(array: [Element]) -> Bool {
for item in array {
if !self.contains(item) { return false }
}
return true
}
}
Run Code Online (Sandbox Code Playgroud)
你可以在这里看到contains方法
这只是一个简单的扩展,用于检查您提供的数组是否在当前数组中(self)
allSatisfy
似乎是您想要的,假设您无法使元素符合Hashable
并使用其他人提到的集合交集方法:
let containsAll = array.allSatisfy(otherArray.contains)
Run Code Online (Sandbox Code Playgroud)
作为Sequence.contains(element)
处理多个元素的补充,请添加以下扩展名:
public extension Sequence where Element : Hashable {
func contains(_ elements: [Element]) -> Bool {
return Set(elements).isSubset(of:Set(self))
}
}
Run Code Online (Sandbox Code Playgroud)
用过的:
list.contains(findList)
Run Code Online (Sandbox Code Playgroud)
由于它使用Set
/,Hashable
因此其性能比Equatable
其他方法好得多。