【问题标题】:How do I split a .txt file into a multidimensional array or dictionary in Swift?如何在 Swift 中将 .txt 文件拆分为多维数组或字典?
【发布时间】:2020-02-16 20:30:54
【问题描述】:

我需要以这种格式解析的 txt 文件的正文:

Name: LittleX
Package: com.ioscreatix.littlex
Description: iPhone X features for Non-X devices on iOS 11, and iPad Dock and PiP for All iOS 11 Devices on iOS 11

Name: InteliX
Package: com.ioscreatix.intelix
Description: Grouped Notifications for iOS 11

我希望我的数组将每个包分别放在一个数组中,该数组按它们的名称值列出,并带有一个用于描述和包的字典。我将如何做到这一点?

这是我目前的代码:

var unfilteredPackagesArray = [String]()
    var secondFilteredPackagesArray = [String]()
    var finalFilteredPackagesArray = [String]()

if let startWordsURL = Bundle.main.url(forResource: "Packages", withExtension: "") {
            if let startWords = try? String(contentsOf: startWordsURL) {
                unfilteredPackagesArray = startWords.components(separatedBy: "\n\n")

                print(unfilteredPackagesArray)
                secondFilteredPackagesArray = startWords.components(separatedBy: "\n")


                finalFilteredPackagesArray = startWords.components(separatedBy: ":")

                print(secondFilteredPackagesArray)

最好的方法是什么?创建 Package 对象并创建一个数组?

【问题讨论】:

  • @JoakimDanielson 问题是我从输入repo.packix.com/Packages.bz2 得到这个txt 文件。这给了我一个 bzip2 包,我仍然不知道如何用 swift 打开它,它是一个 txt 文件。可悲的是,我无法从中获取 json。

标签: arrays swift sorting dictionary parsing


【解决方案1】:

是的,继续!

是的,我认为你应该创建一个Package 结构,然后生成一个array of Package(s)

这是代码。

1。定义包结构?

struct Package {
    let name: String
    let package: String
    let description: String
}

2。加载文件?

guard
    let url = Bundle.main.url(forResource: "Packages", withExtension: "txt"),
    let content = try? String(contentsOf: url)
else { fatalError() }

3。提取线条?

let lines = content
    .components(separatedBy: CharacterSet.newlines)
    .filter { !$0.isEmpty }
    .compactMap { $0.components(separatedBy: ": ").last }

4。提取 3 个数组?

let nameLines = lines.enumerated().filter { $0.offset % 3 == 0 }.map { $0.element }
let packageLines = lines.enumerated().filter { $0.offset % 3 == 1 }.map { $0.element }
let descriptionLines = lines.enumerated().filter { $0.offset % 3 == 2 }.map { $0.element }

5。生成一个包数组???

let packages = zip(nameLines, zip(packageLines, descriptionLines))
    .map { (name: $0, package: $1.0, description: $1.1) }
    .map (Package.init)

6。测试?

print(packages)

[
    Package(name: "LittleX",
            package: "com.ioscreatix.littlex",
            description: "iPhone X features for Non-X devices on iOS 11, and iPad Dock and PiP for All iOS 11 Devices on iOS 11"
    ),
    Package(name: "InteliX",
            package: "com.ioscreatix.intelix",
            description: "Grouped Notifications for iOS 11"
    )
]

【讨论】:

  • 稍后使用 stride 而不是 3 个数组压缩(两次)怎么样?这也将避免 3 个过滤器。附加问题:最后一个compactMap()删除“:”第一部分,是在这里更好,还是在Package的自定义init()方法中删除?
  • @Larme stride 是这种函数式编程方法的一个很好的替代方案。
  • @Larme 关于你的第二个问题,你能详细说明一下吗?
  • 通过.compactMap { $0.components(separatedBy: ": ").last },您将再次迭代整个数组,而这可以在Package.init() 中完成。
  • @Larme 现在我明白你的意思了。你的解决方案确实比我的更快。但我不确定是否有一个初始化器会丢弃部分传递的参数。
猜你喜欢
  • 2018-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-04
  • 1970-01-01
  • 2022-01-03
  • 2013-08-15
  • 1970-01-01
相关资源
最近更新 更多