如何过滤数组中包含指定子字符串的元素?
如何过滤数组中包含指定子字符串的元素?
我懂你现在的痛点——你想从bisacsubjects这个字符串数组里挑出包含"Romance"子串的元素,但之前的代码直接用数组的caseInsensitiveContains,它只会找完全等于"Romance"的数组元素,自然搜不到那些像"Fiction | Romance | Fantasy"这种带子串的项对吧?
问题出在你调用的是数组的caseInsensitiveContains方法,这个方法的作用是判断数组里是否存在和输入字符串完全匹配的元素,而不是检查每个元素是否包含这个子串。要解决这个问题,我们需要把检查的粒度细化到数组里的每一个字符串元素,逐个判断它是否包含目标子串。
给你修改后的代码,还顺便帮你处理了可能的nil情况(避免强制解包!导致崩溃):
var filteredOptions: [BookFromMatchingData] { return shuffleEm.filter { book in // 先安全解包bisacsubjects,避免nil崩溃 guard let subjects = book.iBooks.bisacsubjects else { return false } // 检查数组中是否有任意一个字符串包含"Romance"(不区分大小写) return subjects.contains { subject in subject.range(of: "Romance", options: .caseInsensitive) != nil } } }
如果你觉得用range(of:)有点绕,也可以用转小写的方式实现不区分大小写的匹配,代码会更直观:
var filteredOptions: [BookFromMatchingData] { return shuffleEm.filter { book in guard let subjects = book.iBooks.bisacsubjects else { return false } return subjects.contains { subject in subject.lowercased().contains("romance") } } }
这里有几个关键细节要注意:
- 永远避免强制解包
!,用guard let或者if let处理可选值,能有效避免运行时崩溃 - 我们用了数组的
contains(where:)方法,它会遍历数组中的每个元素,只要有一个元素满足闭包里的条件,就会返回true - 两种写法都能实现需求,你可以根据自己的编码习惯选择:
range(of:options:)支持更多匹配选项(比如同时忽略大小写和音标符号),转小写的方式更简单易懂
内容来源于stack exchange
相关产品推荐
相关产品推荐

