如何在对象数组中查找特定的字符串,在Swift中搜索每个对象?

时间:2018-10-10 17:36:34

标签: arrays swift object

我已经设置了各种类型的对象数组(3个对象,其中包含一个String,Double,String,Double)

我正在寻找返回“特定字符串”的数组中的第一个索引。

如何快速执行此操作?
我已经尝试过.contains.indexOf.first,但它们都不断给我带来错误

错误是:

  

无法将'String'类型的值转换为预期参数类型'( myvalue )throws-> Bool'
  无法将类型' Myobject '的值转换为预期的参数类型...   等)

任何有帮助的想法或信息都是一种祝福。

2 个答案:

答案 0 :(得分:0)

通常不建议使用异类(多个不同)类型的数组。通常,使用它们非常困难,并且您遇到了一个陷阱。

您要寻找的Collection.firstIndex(of:)Sequence.contains(_:)等变体是仅在元素类型为相等时才有条件定义的变体。即使您提到的所有类型都是Equatable,数组的推断类型也是Array<Any>Any不是Equatable,因此您的数组不适合这些功能。

相反,您必须使用基于谓词的函数。它们采用(Element) -> Bool类型的谓词。每个元素作为类型Element的参数的参数传递给谓词,如果元素与您的谓词匹配,则返回true是您的工作,否则返回false。例如,index(where:)将返回使谓词返回true的第一个元素的索引。例如:

let stuff: [Any] = [1, false, "abc"]
if let abcIndex = stuff.index(where: { $0 == "abc" }) {
    print("Found \"abc\" at index \(abcIndex)")
}

不幸的是,Equatable是具有关联类型的协议。就像可以描述类型的模板一样,但它本身并不是名义上的类型。因此,您目前无法执行以下操作:

let equatableStuff: [Equatable] = [1, false, "abc"]
if let abcIndex = stuff.index(of: "abc") {
    print("Found \"abc\" at index \(abcIndex)")
}

答案 1 :(得分:0)

假设您的对象定义如下:

struct MyObject {
    let firstString: String
    let firstDouble: Double
    let secondString: String
    let secondDouble: Double
}

让我们定义三个对象:

let firstObject = MyObject(firstString: "uno",
                           firstDouble: 1,
                           secondString: "un",
                           secondDouble: 11)
let secondObject = MyObject(firstString: "dos",
                           firstDouble: 2,
                           secondString: "deux",
                           secondDouble: 22)
let thirdObject = MyObject(firstString: "uno",
                           firstDouble: 3,
                           secondString: "deux",
                           secondDouble: 33)

并将它们放入数组中

let myArray: [MyObject] = [firstObject, secondObject, thirdObject]

您可以使用first(where:)获取具有firstString属性等于"uno"的第一个元素:

let firstUno: (Int, MyObject)? = myArray
    .enumerated()
    .first(where: { $0.1.firstString == "uno"})

if let uno = firstUno {
    print("First uno index =", uno.0)  //First uno index = 0
    print("First uno object =", uno.1) //First uno object = MyObject(firstString: "uno", firstDouble: 1.0, secondString: "un", secondDouble: 11.0)
}

您可以执行相同的操作以获取第一个对象的secondString属性等于"deux"

let firstDeux: (Int, MyObject)? = myArray
    .enumerated()
    .first(where: { $0.1.secondString == "deux"})

if let deux = firstDeux {
    print("First deux index =", deux.0)  //First deux index = 1
    print("First deux object =", deux.1) //First deux object = MyObject(firstString: "dos", firstDouble: 2.0, secondString: "deux", secondDouble: 22.0)
}