如何使用NSPredicate比较对象数组日期字符串并筛选同dateCreated对象
用NSPredicate筛选数组中dateCreated相同的对象
嘿,这个需求其实很好实现,我给你两种靠谱的方案,你可以根据自己的场景选:
方案一:先转Date再分组筛选(推荐)
直接比较字符串容易踩坑——比如日期字符串的时区、毫秒部分如果有细微差异,字符串比对就会出错。所以先把dateCreated转成Date类型再处理更稳妥:
// 假设你的原始数据数组是这样的 let rawData: [[String: Any]] = [ ["id": "c9967156ad8945fba8cc482cd8aad900", "description": "Hi", "dateCreated": "2018-03-20T06:15:11.000+0000"], ["id": "343e70818044457b884f7ad1907803fa", "description": "The only ", "dateCreated": "2018-03-16T10:20:30.000+0000"], ["id": "abc123xyz", "description": "Another duplicate", "dateCreated": "2018-03-16T10:20:30.000+0000"] ] // 1. 初始化ISO8601日期格式化器,适配你的日期格式 let dateFormatter = ISO8601DateFormatter() dateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] // 2. 按日期分组:把相同Date的对象归为一组 let groupedByDate = Dictionary(grouping: rawData) { item -> Date? in guard let dateStr = item["dateCreated"] as? String else { return nil } return dateFormatter.date(from: dateStr) } // 3. 筛选出有重复的分组(元素数量>1的组) let duplicateDateGroups = groupedByDate.filter { $0.value.count > 1 } // 如果需要把所有重复日期的对象合并成一个数组 let allDuplicateObjects = duplicateDateGroups.values.flatMap { $0 } // 如果你想用NSPredicate单独筛选某一个日期的对象(配合模型类更方便) // 先定义一个模型类(继承NSObject才能用NSPredicate) class DataModel: NSObject { @objc let id: String @objc let desc: String @objc let dateCreated: Date init(id: String, desc: String, dateCreated: Date) { self.id = id self.desc = desc self.dateCreated = dateCreated super.init() } } // 把原始数组转成模型数组 let models = rawData.compactMap { item in guard let id = item["id"] as? String, let desc = item["description"] as? String, let dateStr = item["dateCreated"] as? String, let date = dateFormatter.date(from: dateStr) else { return nil } return DataModel(id: id, desc: desc, dateCreated: date) } // 用NSPredicate筛选指定日期的模型 if let targetDate = dateFormatter.date(from: "2018-03-16T10:20:30.000+0000") { let predicate = NSPredicate(format: "dateCreated == %@", targetDate as CVarArg) let filteredModels = models.filter { predicate.evaluate(with: $0) } // filteredModels就是所有dateCreated为指定日期的对象数组 }
方案二:直接用字符串比对(仅限日期字符串完全一致的场景)
如果你的dateCreated字符串格式绝对统一,没有任何差异,也可以直接用字符串分组+NSPredicate筛选:
// 1. 统计每个日期字符串出现的次数 let dateStrings = rawData.compactMap { $0["dateCreated"] as? String } let dateCountMap = dateStrings.reduce(into: [String: Int]()) { map, str in map[str, default: 0] += 1 } // 2. 找出出现多次的日期字符串 let duplicateDateStrings = dateCountMap.filter { $0.value > 1 }.keys // 3. 用NSPredicate筛选包含这些字符串的对象 let predicate = NSPredicate(format: "dateCreated IN %@", duplicateDateStrings) let filteredArray = rawData.filter { predicate.evaluate(with: $0) }
小提示
优先选方案一,因为日期转成Date类型后,能自动处理时区、格式细微差异等问题,比对结果更准确。如果用方案二,一定要确保所有dateCreated的字符串完全一模一样,包括时区、毫秒部分哦~
内容的提问来源于stack exchange,提问作者iamVishal16
相关产品推荐
相关产品推荐

