本文介绍了检查数组是否包含Swift中另一个数组的所有元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为数组写一个扩展名,以检查一个数组是否包含另一个数组的所有元素,在我的用例中,它是字符串对象,但我一直保持:

I want to write an extension for array to check if an array contains all the elements of another array, in my use case it's string objects but I keep get:

Cannot convert value of type 'T.Generator.Element' to expected argument type '@noescape _ throws -> Bool'

self.contains(item)行中的

大约item

这是我的代码:

extension Array {
    func containsArray<T : SequenceType where T.Generator.Element : Equatable> (array:T) -> Bool{
        for item:T.Generator.Element in array{
            if !self.contains(item) {
                return false
            }
        }
        return true
    }
}

推荐答案

您要求序列元素为Equatable,但它们与数组元素无关.因此

You have required that the sequence elements are Equatable,but they are unrelated to the array elements. Therefore

 if !self.contains(item) { ... }

不编译.

您可能想要的是要求序列元素具有与数组元素相同的类型(应该为Equatable):

What you probably want is to require that the sequence elements have thesame type as the array elements (and that should be Equatable):

extension Array where Element: Equatable {
    func containsArray<T : SequenceType where T.Generator.Element == Element> (array:T) -> Bool {
        for item in array {
            if !self.contains(item) {
                return false
            }
        }
        return true
    }
}

如果仅需要用于数组参数的方法,而不需要一般顺序,然后您可以将声明简化为

If you need the method for array arguments only and not forgeneral sequences then you can simplify the declaration to

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

可以缩写为

extension Array where Element: Equatable {
    func containsArray(array: [Element]) -> Bool {
        return !array.contains { !self.contains($0) }
    }
}

正如@AMomchilov所说,contains()进行线性搜索,因此具有O(M*N)复杂度,其中MN是长度两个数组.您可以为案例定义一个专业化元素是Hashable,并执行成员资格检查针对Set:

As @AMomchilov said, contains() does a linear search, so thishas O(M*N) complexity where M and N are the length ofthe two arrays. You could define a specialization for the casethat the elements are Hashable, and do the membership checkagainst a Set:

extension Array where Element: Hashable {
    func containsArray(array: [Element]) -> Bool {
        let selfSet = Set(self)
        return !array.contains { !selfSet.contains($0) }
    }
}

这是否比以前的方法快?取决于两者数组大小以及元素类型(如何昂贵"是比较元素).

Whether this is faster than the previous method or not would depend on botharray sizes and also on the element type (how "expensive"is it to compare elements).

这篇关于检查数组是否包含Swift中另一个数组的所有元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 16:48