给定时间戳(字符串),我如何在nstextview中找到最接近的时间戳并滚动到它.确切的时间戳可能不存在



i有一个nstextview显示log(价值15 mb的文本(。日志中将有时间戳。示例片段:

2018-04-22 07:54:49 <Homebound> [tests > ... Ending
2018-04-22 07:54:49 <Homebound> [tests > ... Starting
launchctl load /System/Library/
2018-04-22 07:54:50 (null)

我有一个带时间戳记的下拉菜单。时间戳是具有此格式的字符串:

2018-04-22 07:54:49

目前,我可以从下拉菜单中选择一个时间戳,并在NstextView中找到时间戳,然后滚动到时间戳所在。这是代码:

let haystack = myTextBox.string
var needle = failuresArray[selectedIndex - 1][3]
needle.removeLast(2)
// (needle would like like: 2018-04-22 07:54)
if let needleRange = haystack.range(of: needle) {
     myTextBox.scrollRangeToVisible(NSRange(needleRange, in: haystack))
}

我遇到的问题是,确切的时间戳可能不在NstextView中显示的日志中。如何在NstextView中找到最接近的时间戳并滚动到它?

一种方法是在您的时间戳上构建某种索引:

  1. 创建两个变量
    • var index: [String: [Range<String.Index>]]
    • var timestamps: [String]
  2. 当您获得文本时,每个时间戳一次迭代一次,每个时间戳一次:
    • 计算相应的范围
    • 将条目添加到index 将其附加到timestamps
  3. 查询时间戳时,请在timestamps中查找它:
    • 如果存在返回第一个范围
    • 如果没有,请在timestamps上使用二进制搜索获取最接近的搜索并在index中查询其范围

您可能想作为背景任务执行此索引。

我会以几个步骤操作。

  1. 用正则表达式隔离时间戳。
  2. 将时间戳转换为日期(使用日期格式(,然后将日期转换为TimeInterval,您可以从中提取文本字段中的时间参考并获取绝对值。

代码将是:

    let str = <your string>
    var closestRange = NSRange(location: NSNotFound, length: 0)
    var smallestDelta : TimeInterval = TimeInterval.infinity
    let refTimeInterval = <Date from the text field>.timeIntervalSinceReferenceDate
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss"
    if let regex = try? NSRegularExpression(pattern: "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}", options: []) {
        for match in regex.matches(in: str, options: [], range: NSRange(location: 0, length: (str as NSString).length)) {
            let range = match.range(at: 0)
            let substring = (str as NSString).substring(with: range)
            if let date = dateFormatter.date(from: substring) {
                let delta = abs(date.timeIntervalSinceReferenceDate - refTimeInterval)
                if delta < smallestDelta {
                    closestRange = range
                    smallestDelta = delta
                }
            }
        }
    }
 print(closestRange)

正则表达式是一个漫长的话题,但是很容易找到有关它们的信息,例如:https://www.raywenderlich.com/86205/nsregularexpression-swift-swift-tutorial

当然,某种形式的索引会更好,但是我想问题的主要部分是将日期隔离并将其转换为适当的日期。

最新更新