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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25714985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:16:29  来源:igfitidea点击:

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

iosarraysswift

提问by Maxim Shoustin

I have 2 arrays:

我有 2 个数组:

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

I want to determine if listArray contains all findListelements.

我想确定listArray 是否包含所有findList元素。

By the way, elements might be Stringas well or other type.

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

How to do that?

怎么做?

I know that Swift provides containsmethod that works with one item.

我知道 Swift 提供contains了适用于一项的方法。

回答by orkoden

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

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

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

NSSet在检查它是否包含任何对象时比数组快得多。事实上,这就是它的设计目的。

Edit:Using Swift's built-in Set.

编辑:使用 Swift 的内置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)

回答by Jacob Relkin

allSatisfyseems to be what you want, assuming you can't conform your elements to Hashableand use the set intersection approach others have mentioned:

allSatisfy似乎是你想要的,假设你不能使你的元素符合Hashable并使用其他人提到的集合交集方法:

let containsAll = array.allSatisfy(otherArray.contains)

回答by Julien Kode

In Swift 3or Swift 4you can write this:

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
    }
}

You can see the contains method here

你可以在这里看到 contains 方法

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

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

回答by Maxim Shoustin

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

优点 - 方法在第一次失败后停止并且不会继续 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","ddd","eee"]
var findListOfStr:Array<String> = ["bbb","ccc","eee"]
result = arrayContainsArray(listOfStr, findListOfStr) // true


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


(tested on Beta7)

(在 Beta7 上测试)

回答by Antonio

You can use the filtermethod to return all elements of findListwhich are not in list:

您可以使用该filter方法返回所有findList不在 中的元素list

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

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

然后检查返回数组的长度是否为零:

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

Note that his solution traverses the entire findListarray, 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.

请注意,他的解决方案遍历整个findList数组,因此一旦找到非包含元素,它就不会停止。如果您还想知道不包含哪些元素,则应该使用它。

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

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

回答by David James

As a complement to Sequence.contains(element)handling multiple elements, add this extension:

作为Sequence.contains(element)处理多个元素的补充,添加这个扩展:

list.contains(findList)

Used:

用过的:

let a = [2,2]
let b = [1,2,3]

Since this uses Set/Hashableit performs much better than Equatablealternatives.

由于这使用Set/Hashable它比Equatable替代品性能好得多。

回答by Gocy015

None of the previous answers seem to be right.

以前的答案似乎都不对。

consider:

考虑:

let result = list.reduce(true, { 
extension Array {

    func contains<T where T : Equatable>(obj: T) -> Bool {
        return self.filter({
if selectedDates.isEqualTo(originalDates) {
    //Arrays the same hide save button
} else {
    //Arrays not the same, show Save & Discard Changes Button (if not shown)
}
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 } }
? contains(findList, ) :
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
}
})

we wouldn't say that b actually "contains" a, but if your algorithm is based on for-loop & swift's built-in contains(element:)or a set, the above case would pass.

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

回答by Matt Gibson

Right now, I'd probably use something like:

现在,我可能会使用类似的东西:

##代码##

...but then I did just read this article, which might be biasing me towards this kind of solution. You could probably make this more efficient without making it completely unreadable, but it's early and I've not had my coffee.

...但后来我确实读了这篇文章,这可能使我偏向于这种解决方案。您可能可以在不使其完全不可读的情况下提高效率,但现在还早,我还没有喝咖啡。

回答by Ibrahim Yildirim

Extend the Arraywith the following methods:

Array使用以下方法扩展:

##代码##

An example of how you can use it like this:

如何像这样使用它的示例:

##代码##

Shout out to @David Berry for the containmethod.

向@David Berry 喊出包含方法。

回答by Rem-D

This is Maxim Shoustin's answerupdated for Swift 3:

这是Maxim Shoustin为 Swift 3 更新的答案

##代码##