如何过滤JSON空值与Nil值?优化可选配料数组构建方案
高效处理20个可选配料字段的过滤方案
针对批量过滤20个可选配料字段的需求,无需重复编写20次if let判断,以下是几种简洁的实现方式:
方案一:直接数组收集+过滤(仅配料)
在meals结构体中添加计算属性,将所有配料字段放入数组后统一处理:
struct meals: Codable { // 保留原有所有字段 // 过滤后的非空配料数组 var filteredIngredients: [String] { let allIngredients = [ strIngredient1, strIngredient2, strIngredient3, strIngredient4, strIngredient5, strIngredient6, strIngredient7, strIngredient8, strIngredient9, strIngredient10, strIngredient11, strIngredient12, strIngredient13, strIngredient14, strIngredient15, strIngredient16, strIngredient17, strIngredient18, strIngredient19, strIngredient20 ] // 剔除nil值→修剪空格→过滤空字符串 return allIngredients .compactMap { $0?.trimmingCharacters(in: .whitespacesAndNewlines) } .filter { !$0.isEmpty } } }
方案二:配料与对应度量配对过滤
如果需要同时保留配料和对应的度量值,用zip将两个数组配对后处理:
struct meals: Codable { // 保留原有所有字段 // 过滤后的配料-度量配对数组 var filteredIngredientMeasures: [(ingredient: String, measure: String)] { let allIngredients = [ strIngredient1, strIngredient2, strIngredient3, strIngredient4, strIngredient5, strIngredient6, strIngredient7, strIngredient8, strIngredient9, strIngredient10, strIngredient11, strIngredient12, strIngredient13, strIngredient14, strIngredient15, strIngredient16, strIngredient17, strIngredient18, strIngredient19, strIngredient20 ] let allMeasures = [ strMeasure1, strMeasure2, strMeasure3, strMeasure4, strMeasure5, strMeasure6, strMeasure7, strMeasure8, strMeasure9, strMeasure10, strMeasure11, strMeasure12, strMeasure13, strMeasure14, strMeasure15, strMeasure16, strMeasure17, strMeasure18, strMeasure19, strMeasure20 ] return zip(allIngredients, allMeasures) .compactMap { (ingredientOpt, measureOpt) in guard let ingredient = ingredientOpt?.trimmingCharacters(in: .whitespacesAndNewlines), !ingredient.isEmpty else { return nil } let cleanedMeasure = measureOpt?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" return (ingredient, cleanedMeasure) } } }
方案三:Mirror反射(不推荐,仅作扩展)
若字段数量极多,可通过Mirror反射遍历属性,但该方式性能略差且依赖命名规则,非首选:
struct meals: Codable { // 保留原有所有字段 var filteredIngredientsViaMirror: [String] { let mirror = Mirror(reflecting: self) return mirror.children .filter { $0.label?.starts(with: "strIngredient") ?? false } .compactMap { $0.value as? String } .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) } .filter { !$0.isEmpty } } }
注意事项
- 优先选择方案一或方案二,代码可读性高、性能稳定,且能精准控制字段顺序
- 加入
trimmingCharacters是为了过滤仅含空格的无效字段
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

