如何在Swift中获取键值对元组数组?

8

我有一对元组数组pickerDataVisitLocation。我想知道如何使用唯一标识符(例如204)从我的数组中返回键值对位置。

var pickerDataVisitLocation:[(uniqId:Int,location:String)] = [(203,"Home"),(204,"Hospital"),(205,"Other")]
var selectedIndex = pickerDataVisitLocation[1].uniqId
pickerDataVisitLocation[selectedIndex].location //<--fatal error: Index out of range

所以 selectedIndex 是204,因为它是数组中第1个项目的 uniqId。然后你尝试获取 pickerDataVisitLocation[204],但它只有3个项目。问题出在哪里?你期望它做什么? - Connor Neville
2
需要元组吗?我会使用[Int:String]的字典。 - Knight0fDragon
我想要获取uniqId为204的"医院"位置的键值对。 - NinjaDeveloper
selectedIndex 将会是你所给出的代码中的 203、204 或 205,而你的数组只有 3 个元素。 - Rajan Maheshwari
3个回答

19

利用Sequencefirst(where:)方法

你可以利用Sequencefirst(where:)方法,根据元组元素的第一个成员(uniqId)的布尔要求访问数组的第一个元组元素。对于结果元组元素,只需访问元组的第二个成员(location)。

var pickerDataVisitLocation: [(uniqId: Int, location: String)] = 
    [(203, "Home"), (204, "Hospital"), (205, "Other")]

// say for a given uniqId 204
let givenId = 204
let location = pickerDataVisitLocation
               .first{ $0.uniqId == givenId }?.location ?? ""
print(location) // Hospital
如果给定id找不到元组元素,则上述方法将导致结果字符串为空(由于nil合并运算符)。作为替代,您可以使用可选绑定子句仅在从.first返回非nil时继续进行:
var pickerDataVisitLocation: [(uniqId:Int,location:String)] = 
    [(203,"Home"),(204,"Hospital"),(205,"Other")]

// say for a given uniqId 204
let givenId = 204
if let location = pickerDataVisitLocation
                  .first(where: { $0.uniqId == givenId })?.location {
    print(location) // Hospital
}

可能的替代方案:考虑使用字典

最后,由于你的元组元素中的第一个成员uniqId提示了唯一成员,并且它的类型Int是可Hashable的,你可能想考虑使用字典而不是元组数组。这将简化与给定唯一Int id相关联的值的访问,但您将失去字典中“元素”(键-值对)的顺序,因为字典是无序集合。

var pickerDataVisitLocation = [203: "Home", 204: "Hospital", 205: "Other"]

// say for a given uniqId 204
let givenId = 204
if let location = pickerDataVisitLocation[givenId] {
    print(location) // Hospital
}

我希望我能做更多的UpVote。 - NinjaDeveloper
@NinjaDeveloper 很高兴能帮忙 :) - dfrib
嘿@NinjaDeveloper,这已经过去了几年了。我刚开始学习Swift,如何从结构体中访问更多值,而不仅仅是一个“?.位置”,如果我需要所有相关的值呢? - Relativity

3

根据所提供的代码:
请尝试此操作

var pickerDataVisitLocation:[(uniqId:Int,location:String)] = [(203,"Home"),(204,"Hospital"),(205,"Other")]
let selectedIndex = pickerDataVisitLocation[1].uniqId
var location = ""

for item in pickerDataVisitLocation {
    if item.uniqId == selectedIndex {
        location = item.location
    }
}

print(location) //Will print Hospital here

1
您可以尝试像下面这样的内容。
extension Array {
    func tupleWithId(id: Int) -> (uniqId:Int,location:String)? {
        let filteredElements = self.filter { (tuple) -> Bool in
            if let tuple = tuple as? (uniqId:Int,location:String) {
                return tuple.uniqId == id
            }
            return false
        }

        if filteredElements.count > 0 {
            let element = filteredElements[0] as! (uniqId:Int,location:String)
            return element
        }
        return nil
    }
}
var pickerDataVisitLocation:[(uniqId:Int,location:String)] = [(203,"Home"),(204,"Hospital"),(205,"Other")]
var selectedIndex = pickerDataVisitLocation[1].uniqId
pickerDataVisitLocation.tupleWithId(id: selectedIndex)?.location

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接