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
How to determine if one array contains all elements of another array in Swift?
提问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 list
Array contains all findList
elements.
我想确定list
Array 是否包含所有findList
元素。
By the way, elements might be String
as well or other type.
顺便说一下,元素也可能是String
其他类型。
How to do that?
怎么做?
I know that Swift provides contains
method that works with one item.
我知道 Swift 提供contains
了适用于一项的方法。
回答by orkoden
Instead of iterating through arrays and doing filtering yourself, you can use NSSet
to 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)
NSSet
is 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
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:
allSatisfy
似乎是你想要的,假设你不能使你的元素符合Hashable
并使用其他人提到的集合交集方法:
let containsAll = array.allSatisfy(otherArray.contains)
回答by Julien Kode
In Swift 3or Swift 4you can write this:
在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
}
}
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 filter
method to return all elements of findList
which 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 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.
请注意,他的解决方案遍历整个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
/Hashable
it performs much better than Equatable
alternatives.
由于这使用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
回答by Rem-D
This is Maxim Shoustin's answerupdated for Swift 3:
这是Maxim Shoustin为 Swift 3 更新的答案:
##代码##