如何利用Enum与CustomStringConvertible实现频率值与枚举双向转换
解决方案:无需创建第二个枚举,直接在Enum1中实现反向查找
完全不需要额外创建Enum2!我们可以通过给现有Enum1添加静态查找方法,结合CaseIterable协议,轻松实现从targetFrequency值转回对应枚举实例的功能,具体步骤如下:
1. 让Enum1遵守CaseIterable协议
首先给Enum1添加CaseIterable协议,这样我们就能遍历所有枚举case,为反向查找提供基础:
enum Enum1: String, CustomStringConvertible, CaseIterable { // 原有的case定义 case none = "None" case weekly = "Weekly" case monthly = "Monthly" case quarterly = "Quarterly" case semiannually = "Semi-Annually" case annually = "Annually" // 原有的description、timePeriod、targetFrequency属性 var description: String { switch self { case .none: return "None" case .weekly: return "Weekly" case .monthly: return "Monthly" case .quarterly: return "Quarterly" case .semiannually: return "Semi-Annually" case .annually: return "Annually" } } var timePeriod: DateComponents { switch self { case .none: return DateComponents(day: 0) case .weekly: return DateComponents(day: 7) case .monthly: return DateComponents(month: 1) case .quarterly: return DateComponents(month: 3) case .semiannually: return DateComponents(month: 6) case .annually: return DateComponents(year: 1) } } var targetFrequency: Double { switch self { case .none: return 0.0 case .weekly: return 52.0 case .monthly: return 12.0 case .quarterly: return 4.0 case .semiannually: return 2.0 case .annually: return 1.0 } } // 新增的反向查找方法 static func fromTargetFrequency(_ frequency: Double) -> Enum1? { // 遍历所有case,匹配targetFrequency // 注意:如果存在浮点精度问题,可改用近似比较(见下方说明) return allCases.first { $0.targetFrequency == frequency } } }
2. 实际使用示例
现在你可以直接从结构体取出targetFrequency值,转回枚举实例并获取描述字符串:
// 假设从结构体取出的频率值 let savedFrequency = 52.0 if let enumCase = Enum1.fromTargetFrequency(savedFrequency) { print(enumCase.description) // 输出 "Weekly" print(enumCase.rawValue) // 输出 "Weekly" // 也可以直接使用enumCase的其他属性,比如timePeriod } else { // 处理找不到匹配枚举的情况(比如非法的频率值) print("Invalid frequency value") }
关于浮点精度的补充说明
如果targetFrequency值可能因为计算出现微小浮点误差(比如52.0变成51.9999999999),建议把查找方法里的相等判断改成近似比较:
static func fromTargetFrequency(_ frequency: Double) -> Enum1? { let tolerance = 0.0001 // 根据实际需求调整精度阈值 return allCases.first { abs($0.targetFrequency - frequency) < tolerance } }
这样就能完美实现需求,完全不需要额外创建第二个枚举。
内容的提问来源于stack exchange,提问作者user3628240
相关产品推荐
相关产品推荐

