在Swift中,我如何检查数组中是否存在一个元素?Xcode并没有给出包含、包含或拥有的建议,快速搜索这本书也一无所获。知道怎么检查这个吗?我知道有一个方法找到返回索引号,但是否有一个方法返回一个布尔像ruby的#include??

我需要的例子:

var elements = [1,2,3,4,5]
if elements.contains(5) {
  //do something
}

当前回答

你可以为Array添加一个扩展:

extension Array {
     func contains<T>(_ object: T) -> Bool where T: Equatable {
         !self.filter {$0 as? T == object }.isEmpty
     }
 }

这可以用于:

if myArray.contains(myItem) {
   // code here
}

其他回答

包含等于的属性的数组

yourArray.contains(where: {$0.propertyToCheck == value })

返回布尔值。

数组

let elements = [1, 2, 3, 4, 5, 5]

检查元素是否存在

elements.contains(5) // true

获取元素索引

elements.firstIndex(of: 5) // 4
elements.firstIndex(of: 10) // nil

获取元素计数

let results = elements.filter { element in element == 5 }
results.count // 2

你可以为Array添加一个扩展:

extension Array {
     func contains<T>(_ object: T) -> Bool where T: Equatable {
         !self.filter {$0 as? T == object }.isEmpty
     }
 }

这可以用于:

if myArray.contains(myItem) {
   // code here
}

(3)迅速

检查数组中是否存在元素(满足某些条件),如果存在,则继续处理第一个这样的元素

如果意图是:

要检查数组中是否存在一个元素(/满足一些布尔标准,不一定是相等性测试), 如果是,继续处理第一个这样的元素,

然后包含(_:)作为蓝图序列的替代是序列的第一个(where:):

let elements = [1, 2, 3, 4, 5]

if let firstSuchElement = elements.first(where: { $0 == 4 }) {
    print(firstSuchElement) // 4
    // ...
}

在这个虚构的例子中,它的使用可能看起来很愚蠢,但是如果查询非基本元素类型的数组中是否存在满足某些条件的元素,它是非常有用的。如。

struct Person {
    let age: Int
    let name: String
    init(_ age: Int, _ name: String) {
        self.age = age
        self.name = name
    }
}

let persons = [Person(17, "Fred"),   Person(16, "Susan"),
               Person(19, "Hannah"), Person(18, "Sarah"),
               Person(23, "Sam"),    Person(18, "Jane")]

if let eligableDriver = persons.first(where: { $0.age >= 18 }) {
    print("\(eligableDriver.name) can possibly drive the rental car in Sweden.")
    // ...
} // Hannah can possibly drive the rental car in Sweden.

let daniel = Person(18, "Daniel")
if let sameAgeAsDaniel = persons.first(where: { $0.age == daniel.age }) {
    print("\(sameAgeAsDaniel.name) is the same age as \(daniel.name).")
    // ...
} // Sarah is the same age as Daniel.

使用.filter{…某些条件。First可以替换为First(其中:)。后者更好地显示了意图,并且比.filter可能的非惰性工具具有性能优势,因为这些工具将在提取(可能的)第一个通过过滤器的元素之前传递整个数组。


检查数组中是否存在元素(满足某些条件),如果存在,则删除第一个这样的元素

下面的评论质疑道:

如何从数组中删除firstSuchElement ?

与上面类似的用例是删除满足给定谓词的第一个元素。为此,可以使用Collection的index(where:)方法来查找实现谓词的第一个元素的索引,然后使用array To的remove(at:)方法(可能;如果它存在)删除该元素。

var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]

if let indexOfFirstSuchElement = elements.index(where: { $0 == "c" }) {
    elements.remove(at: indexOfFirstSuchElement)
    print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
}

或者,如果你想从数组中删除元素并使用它,应用Optional:s map(_:)方法有条件地(for .some(…)return from index(where:))使用result from index(where:)从数组中删除并捕获被删除的元素(在可选的绑定子句中)。

var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]

if let firstSuchElement = elements.index(where: { $0 == "c" })
    .map({ elements.remove(at: $0) }) {

    // if we enter here, the first such element have now been
    // remove from the array
    print(elements) // ["a", "b", "d", "e", "a", "b", "c"]

    // and we may work with it
    print(firstSuchElement) // c
}

注意,在上面虚构的例子中,数组成员是简单的值类型(String实例),因此使用谓词来查找给定的成员有点过分,因为我们可以简单地使用@DogCoffee的回答中所示的更简单的index(of:)方法来测试是否相等。但是,如果将上面的查找-删除方法应用于Person示例,则使用index(where:)和谓词是合适的(因为我们不再测试是否相等,而是测试是否满足提供的谓词)。

Swift 4.2 + 通过下面的函数,可以很容易地验证实例是否是数组。

func verifyIsObjectOfAnArray<T>(_ object: T) -> Bool {
   if let _ = object as? [T] {
      return true
   }

   return false
}

甚至你也可以像下面这样访问它。如果对象不是数组,你将收到nil。

func verifyIsObjectOfAnArray<T>(_ object: T) -> [T]? {
   if let array = object as? [T] {
      return array
   }

   return nil
}