swift - 计算 Swift 字符串中的行数

标签 swift unicode line-endings

从 Web 服务读取一个中等大小的文件(大约 500kByte)后,我有一个常规的 Swift 字符串()最初编码在 .isolatin1 中。在实际拆分之前,我想(快速)计算行数以便能够初始化进度条。

实现此目标的最佳 Swift 习惯用法是什么?

我想到了以下内容:

let linesCount = lines.reduce(into: 0) { (count, letter) in
   if letter == "\r\n" {
      count += 1
   }
}

这看起来还不错,但我在问自己是否有更短/更快的方法来做到这一点。 characters 属性提供对一系列 Unicode 字符的访问,这些字符将 \r\n 视为唯一的实体。用所有 CharacterSet.newlines 检查这个是行不通的,因为 CharacterSet 不是一组 Character 而是一组 Unicode.Scalar (在我的书中有点违反直觉)这是一组代码点(其中\r\n 算作两个代码点),而不是字形 .尝试

var lines = "Hello, playground\r\nhere too\r\nGalahad\r\n"
lines.unicodeScalars.reduce(into: 0) { (cnt, letter) in
if CharacterSet.newlines.contains(letter) {
    cnt += 1
}

将计数为 6 而不是 3。所以这比上述方法更通用,但它不能正确处理 CRLF 行结尾。

有没有一种方法允许更多的行结束约定(如 CharacterSet.newlines 中),同时仍能为 CRLF 获得正确的结果?能否用更少的代码计算行数(同时仍保持可读性)?

最佳答案

如果您可以在 NSString 上使用 Foundation 方法,我建议使用

enumerateLines(_ block: @escaping (String, UnsafeMutablePointer<ObjCBool>) -> Void)

这是一个例子:

import Foundation

let base = "Hello, playground\r\nhere too\r\nGalahad\r\n"
let ns = base as NSString

ns.enumerateLines { (str, _) in
    print(str)
}

考虑到所有换行符类型,例如“\r\n”、“\n”等,它正确地分隔了行:

Hello, playground
here too
Galahad

在我的示例中,我打印了这些行,但如果您需要的话,对它们进行计数是微不足道的 - 我的版本仅用于演示。

关于swift - 计算 Swift 字符串中的行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46490920/

相关文章:

ios - 检测 Sprite 纹理内的触摸而不是整个框架 iOS Swift SpriteKit?

ios - 在检索 JSON 数据时,让完成 block 返回 Void 有什么意义?

git - 'git diff' 中的 ^M 是什么意思?

windows - 什么行尾用于跨平台兼容性?

c++ - 从 NFD 到 NFC 的 OSX 和 C++ unicode 转换

git - 有没有办法强制 git add 忽略行结束问题?

ios - 我有一个仅当我的 UITableView 为空时才可见的 UILabel。如何在 Swift 中将该标签的文本居中?

html - 使用 NSHTMLTextDocumentType 属性在 UITextView 中使用无序列表重复项目符号

java - 带有特殊/unicode 字符的 toLowerCase 会引发异常

ios - 如何将通用字符名称转换为其在 objective-c 中的实际值?