#ios #arrays #swift #tuples #key-pair
#iOS #массивы #swift #Кортежи #пара ключей
Вопрос:
У меня есть пары кортежей массива pickerDataVisitLocation.просто я хочу знать, как вернуть местоположение пары ключ-значение из моего массива, используя uniqId ex 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
Комментарии:
1. Так
selectedIndex
же, как и 204, поскольку этоuniqId
элемент 1 в вашем массиве. Затем вы пытаетесь получитьpickerDataVisitLocation[204]
, но в нем всего 3 элемента. В чем проблема? Что вы ожидаете от этого?2. Нужен ли вообще кортеж? Я бы просто сделал словарь
[Int:String]
3. я хочу получить местоположение пары значений «Больница», у которого uniqId равен 204
4.
selectedIndex
это будет тот, который вы указали, т.е. 203,204,205 в соответствии с этим кодом, и ваш массив содержит только 3 элемента
Ответ №1:
Используйте метод Sequence
‘s first(where:)
Вы могли бы использовать Sequence
‘s first(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
Если элемент кортежа не может быть найден для данного идентификатора, описанный выше метод приведет к пустой результирующей строке (из-за оператора объединения nil). В качестве альтернативы вы можете использовать необязательное предложение привязки, чтобы продолжить только для nil
невозврата из .first
:
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
идентификаторами, но вы потеряете порядок «элементов» (пар ключ-значение) в словаре, поскольку словари представляют собой неупорядоченные коллекции.
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
}
Комментарии:
1. Жаль, что я не могу сделать больше голосов
2. @NinjaDeveloper рад помочь 🙂
3. Привет, @NinjaDeveloper, с тех пор прошло несколько лет. Я новичок в swift, как я могу получить доступ к большему количеству значений из структуры вместо одного «? .location», что, если я хочу, чтобы все значения соответствовали.
Ответ №2:
В соответствии с приведенным кодом:
попробуйте это
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
Ответ №3:
Вы могли бы попробовать что-то вроде приведенного ниже.
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