【问题标题】:How do I find a specific String in an array of Objects, searching through each Object in Swift?如何在对象数组中找到特定的字符串,在 Swift 中搜索每个对象?
【发布时间】:2018-10-10 17:36:33
【问题描述】:

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

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

如何快速做到这一点?
我试过.contains.indexOf.first,但他们都一直给我错误

错误是:

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

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

【问题讨论】:

  • 到目前为止你尝试过什么代码?你是如何定义那个数组的?请在您的问题中包含所有相关代码
  • "我已经尝试过 .contains、.indexOf、.first," 向我们展示您的尝试!我们会帮助您解决问题。
  • “任何有用的想法或信息都是一种祝福”:)

标签: arrays swift object


【解决方案1】:

假设您的对象定义如下:

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

【讨论】:

  • 谢谢 Carpsen90,这正是我想要的,而且效果很好。
  • @user8027140 很高兴为您提供帮助,如果此答案解决了您的问题,请单击答案旁边的复选标记将其标记为已接受。请参阅:How does accepting an answer work? 了解更多信息
【解决方案2】:

通常不建议使用异构(多种不同)类型的数组。它们通常很难使用,而且您遇到了其中一个陷阱。

您正在寻找的Collection.firstIndex(of:)Sequence.contains(_:) 等的变体是仅在元素类型可相等时有条件定义的变体。尽管您提到的所有类型都是Equatable,但Array 的推断类型是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)")
}

【讨论】:

  • 这用于具有名称、制造日期、制造商和成本的对象的多部分数组。使用您提供的内容最终会给我一个:二元运算符'=='不能应用于'myObject'和'String'类型的操作数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-06
  • 1970-01-01
  • 2017-08-27
  • 1970-01-01
  • 2020-11-19
  • 2015-02-26
相关资源
最近更新 更多