[英]Swift: How to access variable element of an enum?
几个小时以来,我一直在努力获取枚举的可变元素。
“ Swifticons ” -pod为我提供了以下枚举:
public enum WeatherType: Int {
static var count: Int {
return weatherIcons.count
}
public var text: String? {
return weatherIcons[rawValue]
}
case alien, barometer, celsius, owm300, owm301, owm302, and200moreOfTheseNames
}
private let weatherIcons = ["\u{f075}", "\u{f079}", and202moreOfTheseFontCharacters]
从一个外部API( openWeatherMap.org ),我仅获得一个天气代码(比如说“ 300”),并且我想访问图标“ owm300”。
但是,如何在不知道rawValue的情况下访问枚举的此元素(即-198)?
我想到的最简单的方法之一就是创建某种映射字典,在其中您可以跟踪天气响应代码和它映射到的WeatherType,
let weatherCodeMapping: [Int: WeatherType] = [300: .owm300,
301: .owm301,
302: .owm302]
有了这个,您就不需要知道任何特定的rawValue,只需通过以下方式获取代码,
let weatherType = weatherCodeMapping[weatherCode]
然后根据weatherType为图像创建其他映射。
let weatherIcon = weatherIconMapping[weatherType]
或直接从天气代码到图标创建单个映射。
这是计划:
WeatherType
由Int
支持)。 String
映射到WeatherType
。 WeatherType?
因为我们会遇到一个未知值。 这是代码:
extension WeatherType {
// just some little convenience
private typealias W = WeatherType
// 1. define the sequence of all cases
private static func allCases() -> AnySequence<W> {
return AnySequence { () -> AnyIterator<W> in
var raw = 0
return AnyIterator {
// Iterates while raw value can be converted to an enum case
if let next = W(rawValue: raw) {
raw += 1
return next
}
return nil
}
}
}
// 2. Static properties are lazy so we'll use them to store the dictionary with String to WeatherType mapping
private static let typeMap = W.allCases().reduce([String: W]()) { acc, next in
var acc = acc
acc[String(describing: next)] = next
return acc
}
// 3. Declare the mapping function
static func from(string: String) -> WeatherType? {
return W.typeMap[string]
}
}
这是一个小测试:
let str = "301"
let type = WeatherType.from(string: "owm\(str)")
print(type == .owm301)
Swift当前没有枚举实例的可枚举序列。 您拥有的一种选择是复制图标名称列表 ,然后搜索图标的名称,并将该索引用作枚举的rawValue:
let weatherIcons = [...]
let iconName = "owm300"
let possibleIconIndex = weatherIcons.index {
$0.caseInsensitiveCompare(iconName) == .orderedSame
}
if let iconIndex = possibleIconIndex {
let weatherIcon = WeatherIcon(rawValue: iconIndex)!
// ...
} else {
// graceful fallback for when the weather icon is missing
}
当然,您需要弄清楚从服务获取的数据和枚举名称之间的映射关系,但这可能很简单,例如"owm\\(weatherCode)"
。
当Swift 4.2登陆时,您将能够使您的枚举符合一个名为CaseIterable
的新协议。 符合它的枚举将获得allCases
静态变量的综合实现。 然后,您将可以使用该枚举自动构建字符串到枚举的字典:
let nameToEnum = WeatherIcon.allCases.map { (String($0), $0) }
let mapping = Dictionary(uniqueKeysWithValues: nameToEnum)
但是,这将要求WeatherIcon
声明为CaseEnumerable
一致性,因为添加extension
不会起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.