【问题标题】:Swift - Write an Array to a Text FileSwift - 将数组写入文本文件
【发布时间】:2014-09-18 13:43:37
【问题描述】:

我从一个包含几千行纯文本的文件中读入了 myArray(原生 Swift)..

myData = String.stringWithContentsOfFile(myPath, encoding: NSUTF8StringEncoding, error: nil)
var myArray = myData.componentsSeparatedByString("\n")

我更改了 myArray 中的一些文本(没有必要粘贴任何代码)。

现在我想将 myArray 的更新内容写入一个新文件。 这个我试过了..

let myArray2 = myArray as NSArray
myArray2.writeToFile(myPath, atomically: false)

但文件内容是 plist 格式。

有没有办法在 Swift(或桥接 Swift)中将文本字符串数组写入文件(或遍历数组并将每个数组项附加到文件)?

【问题讨论】:

    标签: arrays file text swift output


    【解决方案1】:

    正如drawag 在接受的帖子中指出的那样,您可以从数组中构建一个字符串,然后在该字符串上使用writeToFile 方法。

    但是,您可以简单地使用 Swift 的 Array.joinWithSeparator 以更少的代码和可能更好的性能完成相同的任务。

    例如:

    // swift 2.0
    let array = [ "hello", "goodbye" ]
    let joined = array.joinWithSeparator("\n")
    do {
        try joined.writeToFile(saveToPath, atomically: true, encoding: NSUTF8StringEncoding)
    } catch {
        // handle error
    }
    
    // swift 1.x
    let array = [ "hello", "goodbye" ]
    let joined = "\n".join(array)
    joined.writeToFile(...)
    

    【讨论】:

    • 啊类似于 perl/javascript 的东西。它又短又甜,我喜欢。如果我可以投票 100 倍,我会的。
    • 它改变了,在 Swift 5 中它是:array.joined(separator: "\n")
    【解决方案2】:

    使用 Swift 5,我想使用 Swift 4 你可以使用代码 sn-p 对我来说很好。

    let array = ["hello", "world"]
    let joinedStrings = array.joined(separator: "\n")
    
    do {
        try joinedStrings.write(toFile: outputURL.path, atomically: true, encoding: .utf8)
    } catch let error {
        // handle error
        print("Error on writing strings to file: \(error)")
    }
    

    【讨论】:

      【解决方案3】:

      您需要将数组缩减为字符串:

      var output = reduce(array, "") { (existing, toAppend) in
          if existing.isEmpty {
              return toAppend
          }
          else {
              return "\(existing)\n\(toAppend)"
          }
      }
      output.writeToFile(...)
      

      reduce 方法接受一个集合并将其全部合并到一个实例中。将集合的所有元素合并到原始实例中需要一个初始实例和闭包。

      我的示例将一个空字符串作为其初始实例。然后闭包检查现有输出是否为空。如果是,它只需要返回要追加的文本,否则,它使用String Interpolation 返回现有输出和新元素之间的换行符。

      使用 Swift 的各种语法糖功能,整个简化可以简化为:

      var output = reduce(array, "") { $0.isEmpty ? $1 : "\($0)\n\($1)" }
      

      【讨论】:

      • 这是不必要的复杂,并为每个相邻的两个元素对执行连接。怎么样:let pieces = [ "hello", "goodbye" ]let joined = "\n".join(pieces)
      • @DPlusV,如果您有其他解决方案,请将其作为单独的答案发布。此外,“每当你遇到一个非常草率、不费吹灰之力的帖子,或者一个明显不正确且可能危险地不正确的答案时”,都应该使用反对票。我可能弄错了,但我不相信我的答案适合该类别。如果是,请说明原因。
      • 恕我直言,您的回答在技术上是正确的,但对于这项工作来说是错误的工具。举个例子,仅仅因为可以递归地计算斐波那契项,并不意味着应该。 SO被许多用户用作学习向量。最好提倡良好的做法。其中一些代码最终会出现在我和您将使用的生产软件中。否定不是人身攻击,而更多是对某人的警告“嘿,不要只是复制和粘贴这段代码。”
      • @DPlusV,我个人不认为。反对票是针对不正确或误导性信息的,否则单独的答案可能会根据问题的最佳答案竞争最多的选票。我的评论中更重要的部分是您应该单独提供您的答案,以便它可以更突出地展示。我会自己投票。 (我同意你的回答更好,但我仍然觉得我的回答具有创造性地使用reduce 的价值)
      • 好主意,感谢您成为建设性的 SO'er!
      【解决方案4】:

      Swift 提供了多种循环数组的方法。您可以遍历字符串并一一打印到文本文件。像这样:

      for theString in myArray {
          theString.writeToFile(myPath, atomically: false, encoding: NSUTF8StringEncoding, error: nil);
      }
      

      【讨论】:

      • 这对我不起作用。它只写最后一行。
      • @ricardopereira 我认为它正在编写数组的所有元素。如果您完全按照所示的示例进行操作,那么问题是 myPath 对于每次迭代都是相同的。每次迭代都会覆盖文件以及前一次迭代的内容。无论如何,即使您每次都更新myPath,这也有点尴尬。如果数组有 500 个元素,则需要 500 个文件才能以这种方式存储它。看看@DPlusV 的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-26
      • 2018-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多