首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用NSPredicate比较对象数组中的两个日期字符串?

如何使用NSPredicate比较对象数组中的两个日期字符串?
EN

Stack Overflow用户
提问于 2018-03-20 07:02:46
回答 2查看 114关注 0票数 0

我希望使用NSPredicate比较每个对象的日期。如果对象具有相同的dateCreated,它将返回一个具有相同日期的对象数组。

在下面的字典数组中,0索引具有与另一个索引不同的日期,如何获得这样的数据。

例如:

代码语言:javascript
运行
复制
{
      "Data": [
    {
      "id": "c9967156ad8945fba8cc482cd8aad900",
      "description": "Hi",
      "dateCreated": "2018-03-20T06:15:11.000+0000",

    },
    {
      "id": "343e70818044457b884f7ad1907803fa",
      "description": "The only ",
      "dateCreated": "2018-03-16T17:22:50.000+0000",

    },
    {
      "id": "dd542edfaa364e40ae0ef0562b6831be",
      "description": "The new ",
      "dateCreated": "2018-03-16T17:10:36.000+0000",

    },
    {
      "id": "090f43c83e5b42039f70b133d031e715",
      "description": "The new version ",
      "dateCreated": "2018-03-16T17:08:07.000+0000",

    },
    {
      "id": "b2ddb8fa990843a28f0670d2b88e3d01",
      "description": "Add to the test",
      "dateCreated": "2018-03-16T17:08:07.000+0000",

    }
     ]
    }

#Edit1 1:我正在将dateCreated String对象转换为Date,然后对所需的数据使用NSPredicate。目前,我正在尝试使用NSPredicate

#Edit2 2当前,我不使用NSPredicate。我正在迭代数组的每个元素并比较其日期。

代码语言:javascript
运行
复制
  if let dateCur = dateCreated.dateFromISO8601 {
     if let datePrev = dateCreatedPrev.dateFromISO8601 {
      let curLocal = ISO8601.getStringDate(dateCur).   // dd/MM/yyyy
      let prevLocal = ISO8601.getStringDate(datePrev). // dd/MM/yyyy
      if (curLocal.compare(prevLocal) != .orderedSame {
           //diffrent
      }else {
          //same
      }
     }
  }

我正在使用扩展来实现它。

代码语言:javascript
运行
复制
extension Date {

func getFormatter() -> DateFormatter {
    let formatter = DateFormatter()
    formatter.calendar = Calendar(identifier: .gregorian)
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.timeZone = TimeZone(secondsFromGMT: 0)
    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
    return formatter
}

var iso8601: String {
    return Formatter.iso8601.string(from: self)
}

extension String {
  var dateFromISO8601: Date? {
     return Formatter.iso8601.date(from: self)   // "Mar 22, 2017,    10:22 AM"
  }
}

你能帮帮我吗。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-20 08:51:29

首先,没有必要在Swift中使用NSPredicate (除了需要NSPredicate的API)。

本机filter方法更合适。

我建议解码JSON

代码语言:javascript
运行
复制
let jsonString = """
{
    "Data": [
        {"id": "c9967156ad8945fba8cc482cd8aad900", "description": "Hi", "dateCreated": "2018-03-20T06:15:11.000+0000"},
        {"id": "343e70818044457b884f7ad1907803fa", "description": "The only ", "dateCreated": "2018-03-16T17:22:50.000+0000"},
        {"id": "dd542edfaa364e40ae0ef0562b6831be", "description": "The new ", "dateCreated": "2018-03-16T17:10:36.000+0000"},
        {"id": "090f43c83e5b42039f70b133d031e715", "description": "The new version ", "dateCreated": "2018-03-16T17:08:07.000+0000"},
        {"id": "b2ddb8fa990843a28f0670d2b88e3d01", "description": "Add to the test", "dateCreated": "2018-03-16T17:08:07.000+0000"}
    ]
}
"""

转换为自定义结构

代码语言:javascript
运行
复制
struct Root : Decodable {
    private enum CodingKeys : String, CodingKey { case items = "Data" }
    let items : [Item]
}

struct Item : Decodable {
    let id, description : String
    let dateCreated : Date
}

解码器使用自定义日期格式化程序正确地解码ISO8601日期。

代码语言:javascript
运行
复制
let data = Data(jsonString.utf8)
let decoder = JSONDecoder()
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SZ"
decoder.dateDecodingStrategy = .formatted(dateFormatter)

do { 
    let result = try decoder.decode(Root.self, from: data)

数组位于result.items中。现在可以按特定日期对数组进行filter。在本例中,引用日期是用DateComponents硬编码创建的。

代码语言:javascript
运行
复制
    let components = DateComponents(timeZone: TimeZone(secondsFromGMT: 0), year:2018, month:03, day:16, hour:17, minute:8, second:7)
    let date = Calendar.current.date(from: components)!
    let filteredItems = result.items.filter { $0.dateCreated == date }
    print(filteredItems)
} catch { print(error) }

如果要在数组中查找给定日期的所有匹配记录,请使用循环

代码语言:javascript
运行
复制
for item in result.items {
    let filteredItems = result.items.filter { $0.dateCreated == item.dateCreated }
    if filteredItems.count > 1 { print(filteredItems) }
}
票数 1
EN

Stack Overflow用户

发布于 2018-03-20 10:10:34

您可以查看Dictionary的初始化器init(grouping:by:),它是在Swift 4中引入的。

你应该有你的对象数组。然后,您可以将它们分组到[String:Object]中,其中key将以yyyy-MM-dd格式作为String作为您的Date

先决条件:您的dateCreated属性应该是Date格式。

代码语言:javascript
运行
复制
let groupedObjectBySameDate = Dictionary(grouping: objects) { (object) -> String in
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    return formatter.string(from: object.dateCreated)
}

举个例子:

由于我不知道您的数据结构,所以我提供了一个简单的示例,可以帮助您了解正在发生的事情。

代码语言:javascript
运行
复制
var dateFormatter: DateFormatter {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SZ"
    formatter.locale = Locale(identifier: "en_US_POSIX")
    return formatter
}
let stringDates = ["2018-03-20T06:15:11.000+0000", "2018-03-16T17:22:50.000+0000", "2018-03-16T17:10:36.000+0000", "2018-03-16T17:08:07.000+0000", "2018-03-16T17:08:07.000+0000"]
let dates = stringDates.map { (each) -> Date in
    return dateFormatter.date(from: each) ?? Date(timeIntervalSinceReferenceDate: 0)
}

let groupedObjectBySameDate = Dictionary(grouping: dates) { (date) -> String in
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    return formatter.string(from: date)
}
print(groupedObjectBySameDate)

// This will produce:
// [
//     "2018-03-20": [2018-03-20 06:15:11 +0000], 
//     "2018-03-16": [2018-03-16 17:22:50 +0000, 2018-03-16 17:10:36 +0000, 2018-03-16 17:08:07 +0000, 2018-03-16 17:08:07 +0000]
// ]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49378109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档