Ios 如何确定Swift中一个数组是否包含另一个数组的所有元素?

Ios 如何确定Swift中一个数组是否包含另一个数组的所有元素?,ios,arrays,swift,Ios,Arrays,Swift,我有两个阵列: var list:Array<Int> = [1,2,3,4,5] var findList:Array<Int> = [1,3,5] var列表:数组=[1,2,3,4,5] var findList:Array=[1,3,5] 我想确定list数组是否包含所有findList元素 顺便说一下,元素可能是String或其他类型 怎么做 我知道Swift提供了包含方法,可用于一个项目。考虑以下通用方法: func arrayContainsArray&

我有两个阵列:

var list:Array<Int> = [1,2,3,4,5]
var findList:Array<Int> = [1,3,5]
var列表:数组=[1,2,3,4,5]
var findList:Array=[1,3,5]
我想确定
list
数组是否包含所有
findList
元素

顺便说一下,元素可能是
String
或其他类型

怎么做


我知道Swift提供了
包含
方法,可用于一个项目。

考虑以下通用方法:

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
}

listAsInt:Array=[1,2,3,4,5]
findlistaint:Array=[1,3,5,7,8,9]
结果=ArrayContainesArray(listAsInt,findListAsInt)//false

var-listOfStr:Array=[“aaa”、“bbb”、“ccc”、“ddd”、“eee”]
var findListOfStr:Array=[“bbb”、“ccc”、“eee”]
结果=ArrayContainesArray(listOfStr,findListOfStr)//true

listOfStr:Array=[“aaa”、“bbb”、“ccc”、“ddd”、“eee”]
findListOfStr:Array=[“bbb”、“ccc”、“eee”、“sss”、“fff”、“ggg”]
结果=ArrayContainesArray(listOfStr,findListOfStr)//false


(在Beta7上测试)

现在,我可能会使用以下内容:

let result = list.reduce(true, { $0 ? contains(findList, $1) : $0 })

…但后来我就这么做了,这可能会使我倾向于这种解决方案。您可以在不使其完全不可读的情况下使其更有效,但时间还早,而且我还没有喝过咖啡。

您可以使用
过滤器
方法返回
查找列表
中不在
列表
中的所有元素:

let notFoundList = findList.filter( { contains(list, $0) == false } )
然后检查返回数组的长度是否为零:

let contained = notFoundList.count == 0
请注意,他的解决方案遍历整个
findList
数组,因此它不会在找到不包含的元素时立即停止。如果您还想知道哪些元素未包含,则应该使用它


如果您只需要一个布尔值来说明是否包含所有元素,那么Maxim Shoustin提供的解决方案效率更高。

您可以使用
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)

使用以下方法扩展
数组

extension Array {

    func contains<T where T : Equatable>(obj: T) -> Bool {
        return self.filter({$0 as? T == obj}).count > 0
    }

    func isEqualTo< T : Equatable> (comparingArray : [T]) -> Bool {

        if self.count != comparingArray.count {
            return false
        }

        for e in comparingArray {
            if !self.contains(e){
                return false
            }
        }

        return true
    }
}
向@David Berry大声喊出方法

这是对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
}
func数组内容数组
(src:S,lookFor:S)->Bool其中S.Iterator.Element:equalable{
对于lookFor中的v:S.Iterator.Element{
如果src.包含(v)=false{
返回错误
}
}
返回真值
}

Swift 3Swift 4中,您可以编写以下内容:

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


这只是一个简单的扩展,用于检查您提供的数组是否在当前数组(self)

中,作为对
序列的补充。包含(element)
处理多个元素,请添加此扩展:

public extension Sequence where Element : Hashable {
    func contains(_ elements: [Element]) -> Bool {
        return Set(elements).isSubset(of:Set(self))
    }
}
使用:


因为它使用了
Set
/
Hashable
方法,所以它的性能比
equalable
方法要好得多。

前面的答案似乎都不正确

考虑:

let a = [2,2]
let b = [1,2,3]
我们不会说b实际上“包含”a,但如果您的算法基于for-loop&swift的内置
contains(element:)
或一个集合,则上述情况将通过。

似乎是您想要的,假设您无法将您的元素与
Hashable
一致,并使用其他人提到的集合交集方法:

let containsAll = subArray.allSatisfy(largerArray.contains)

如果需要确定,则一个阵列是另一个阵列的子阵列

公共扩展数组,其中元素:equalable{
func isSuperArray(属于数组:数组)->Bool{
警卫
count>=array.count,
让index=array.first.flatMap(索引(of:),
!index.isEmpty else{
返回错误
}
让arraysForComparison=索引
.compactMap{index->[Element]?在
保护索引+(array.count-1)[索引]{
枚举()
.filter{element==0.1}
.map{index,{in index}
}
}
用法示例:

让数组1=[1,2,3,4]
设array2=[2,3]
打印(array1.isSuperArray(of:array2))//true
print(array2.issubray(of:array1))//true
打印(array2.isSuperArray(of:array1))//false
打印(array1.issubray(of:array2))//false

我自己使用这组扩展方法。我希望这段代码有助于:


//  Array + CommonElements.swift


import Foundation

public extension Array where Element: Hashable {

    func set() -> Set<Array.Element> {
        return Set(self)
    }

    func isSubset(of array: Array) -> Bool {
        self.set().isSubset(of: array.set())
    }

    func isSuperset(of array: Array) -> Bool {
        self.set().isSuperset(of: array.set())
    }

    func commonElements(between array: Array) -> Array {
        let intersection = self.set().intersection(array.set())
        return intersection.map({ $0 })
    }

    func hasCommonElements(with array: Array) -> Bool {
        return self.commonElements(between: array).count >= 1 ? true : false
    }
}

//数组+CommonElements.swift
进口基金会
公共扩展数组,其中元素:可哈希{
func set()->set{
返回集(自身)
}
func isSubset(属于数组:数组)->Bool{
self.set().isSubset(of:array.set())
}
func isSuperset(数组的名称:数组)->Bool{
self.set()
}
func commonElements(数组之间:数组)->array{
让交点=self.set().intersection(array.set())
返回intersection.map({$0})
}
func hasCommonElements(带数组:array)->Bool{
返回self.commonElements(介于:数组之间)。计数>=1?true:false
}
}

这两个集合如何相等?据我所知,这只是从每个数组生成一个唯一的集合,然后对它们进行比较?这些集合是相等的。它们不一样。
listSet==findListSet
是错误的。你完全正确。我再次阅读了这个问题,意识到我误解了它,使用了错误的方法正确的使用方法是
isSubsetOfSet(u.otherSet:)
。谢谢。您现在可以使用Swift的内置集类型进行此操作。这会给出
let list=[1,2,3,4,5]
let findList=[1,3,3,5]的预期结果吗
?当使用
Set
时,
findList
列表的一个子集,但不仅仅是在比较数组时。我尝试在Playdool中测试这一点…在这一行“if contains(src,v)=false{”。我得到错误“contains不可用:调用序列上的contains()方法”有什么想法吗?注意,有几个答案建议使用
equalatable
一致性解决方案,这会产生>=O(n)性能
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
}
extension Array where Element: Equatable {
    func contains(array: [Element]) -> Bool {
        for item in array {
            if !self.contains(item) { return false }
        }
        return true
    }
}
public extension Sequence where Element : Hashable {
    func contains(_ elements: [Element]) -> Bool {
        return Set(elements).isSubset(of:Set(self))
    }
}
list.contains(findList)
let a = [2,2]
let b = [1,2,3]
let containsAll = subArray.allSatisfy(largerArray.contains)

//  Array + CommonElements.swift


import Foundation

public extension Array where Element: Hashable {

    func set() -> Set<Array.Element> {
        return Set(self)
    }

    func isSubset(of array: Array) -> Bool {
        self.set().isSubset(of: array.set())
    }

    func isSuperset(of array: Array) -> Bool {
        self.set().isSuperset(of: array.set())
    }

    func commonElements(between array: Array) -> Array {
        let intersection = self.set().intersection(array.set())
        return intersection.map({ $0 })
    }

    func hasCommonElements(with array: Array) -> Bool {
        return self.commonElements(between: array).count >= 1 ? true : false
    }
}