有没有办法将Swift词典打印到控制台?

Tol*_*Hon 73 xcode ios swift

NSDictionary *dictionary = @{@"A" : @"alfa",
                             @"B" : @"bravo",
                             @"C" : @"charlie",
                             @"D" : @"delta",
                             @"E" : @"echo",
                             @"F" : @"foxtrot"};
NSLog(@"%@", dictionary.description);
Run Code Online (Sandbox Code Playgroud)

在控制台上打印出以下内容:

{
    A = alfa;
    B = bravo;
    C = charlie;
    D = delta;
    E = echo;
    F = foxtrot;
}
Run Code Online (Sandbox Code Playgroud)
let dictionary: [String : String] = ["A" : "alfa",
                                     "B" : "bravo",
                                     "C" : "charlie",
                                     "D" : "delta",
                                     "E" : "echo",
                                     "F" : "foxtrot"];
print(dictionary)
Run Code Online (Sandbox Code Playgroud)

在控制台上打印出以下内容:

["B": "bravo", "A": "alfa", "F": "foxtrot", "C": "charlie", "D": "delta", "E": "echo"]
Run Code Online (Sandbox Code Playgroud)

有没有办法在Swift中将它带到漂亮的打印字典,其中每个键值对占用一个新行?

aya*_*aio 83

例如,如果目标是检查字典,则可以使用dump.dump是Swift标准库的一部分.

用法:

let dictionary: [String : String] = ["A" : "alfa",
                                     "B" : "bravo",
                                     "C" : "charlie",
                                     "D" : "delta",
                                     "E" : "echo",
                                     "F" : "foxtrot"]

dump(dictionary)
Run Code Online (Sandbox Code Playgroud)

输出:

在此输入图像描述


dump 通过反射(镜像)打印对象的内容.

阵列的详细视图:

let names = ["Joe", "Jane", "Jim", "Joyce"]
dump(names)
Run Code Online (Sandbox Code Playgroud)

打印:

▿4个元素
- [0]:乔
- [1]:简
- [2]:吉姆
- [3]:乔伊斯

对于字典:

let attributes = ["foo": 10, "bar": 33, "baz": 42]
dump(attributes)
Run Code Online (Sandbox Code Playgroud)

打印:

▿3个键/值对
▿[0] :( 2个元素)
- .0:bar
- .1:
33▿[1] :( 2个元素)
- .0:baz
- .1:
42▿[2] :( 2个元素)
- .0:foo
- .1:10

dump被宣布为dump(_:name:indent:maxDepth:maxItems:).

第一个参数没有标签.

还有其他可用参数,比如name为被检查对象设置标签:

dump(attributes, name: "mirroring")
Run Code Online (Sandbox Code Playgroud)

打印:

▿镜像:3个键/值对
▿[0] :( 2个元素)
- .0:bar
- .1:
33▿[1] :( 2个元素)
- .0:baz
- .1:
42▿[2] :(2个元素)
- .0:foo
- .1:10

您还可以选择仅打印一定数量的项目maxItems:,以将对象解析到一定深度maxDepth:,并更改打印对象的缩进indent:.

  • 这不是很好的打印JSON,这只是将一个变量转储到控制台 - 无效的JSON.虽然它确实符合OP的需求,但我相信这个问题需要重新措辞才能与之匹配. (3认同)
  • @JamesWolfe`这不是打印好的JSON`,没人说是。OP询问了漂亮的Swift字典打印-除了几个离题的回答者,没有人谈论JSON。OP的问题根本不是关于JSON的。 (3认同)

Jal*_*koo 80

SWIFT 3

将字典转换为'AnyObject'对我来说是最简单的解决方案:

let dictionary = ["a":"b",
                  "c":"d",
                  "e":"f"]
print("This is the console output: \(dictionary as AnyObject)")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这比转储选项更容易阅读,但请注意,它不会为您提供键值的总数.

  • 这是一种比倾倒更好的方式和方式 (7认同)
  • 很酷,但我不明白为什么它的工作. (3认同)

Irs*_*med 69

po解决方案

对于那些想要在控制台中看到带有转义序列的字典作为JSON的人,这是一个简单的方法

(LLDB)p print(String(data: try! JSONSerialization.data(withJSONObject: object, options: .prettyPrinted), encoding: .utf8 )!)

  • 检查[此评论](/sf/answers/4473722851/)以在 lldb 别名中利用它,这样您就不必每次都键入它! (2认同)

Luc*_*tti 32

使用功能编程的另一种方式

dictionary.forEach { print("\($0): \($1)") }
Run Code Online (Sandbox Code Playgroud)

产量

B: bravo
A: alfa
F: foxtrot
C: charlie
D: delta
E: echo
Run Code Online (Sandbox Code Playgroud)

  • 这适用于OP的`[String:String]`字典,但对于`[AnyHashable:Any]`字典来说并不是很好,如果一个值是一个字典,你就会回到Swift的非漂亮打印. (3认同)

Mar*_*o M 21

出于调试目的,我只将数组或字典转换为漂亮的json:

public extension Collection {

    /// Convert self to JSON String.
    /// - Returns: Returns the JSON as String or empty string if error while parsing.
    func json() -> String {
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: self, options: [.prettyPrinted])
            guard let jsonString = String(data: jsonData, encoding: String.Encoding.utf8) else {
                print("Can't create string with data.")
                return "{}"
            }
            return jsonString
        } catch let parseError {
            print("json serialization error: \(parseError)")
            return "{}"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

print("\nHTTP request: \(URL)\nParams: \(params.json())\n")
Run Code Online (Sandbox Code Playgroud)

控制台上的结果:

HTTP request: https://example.com/get-data
Params: {
  "lon" : 10.8663676,
  "radius" : 111131.8046875,
  "lat" : 23.8063882,
  "index_start" : 0,
  "uid" : 1
}
Run Code Online (Sandbox Code Playgroud)


Jam*_*lfe 12

我不会考虑这里提供的很多答案真正相当印刷的JSON,因为当您将结果传递给JSON验证器时,结果无效(通常由于代码包括'='而不是':').

我发现这样做的最简单方法是使用漂亮的打印写入选项将JSON对象转换为数据,然后使用结果数据打印字符串.

这是一个例子:

let jsonData = try! JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)

if let jsonString = String(data: jsonData, encoding: .utf8) {
    print(jsonString)
}
Run Code Online (Sandbox Code Playgroud)

结果:

{
    "jsonData": [
        "Some String"
    ],
    "moreJSONData": "Another String",
    "evenMoreJSONData": {
        "A final String": "awd"
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:有人指出OP没有要求JSON,但我发现建议只是打印或将数据转储到控制台的答案提供非常少的格式(如果有的话),因此不是很好的打印.

我相信尽管OP没有要求JSON,但它是一个可行的答案,因为它是一种更可读的数据格式,而不是由xcode/swift吐出到控制台中的可怕格式.


agi*_*ult 6

根据我在此处的其他答案进行调整。

使用 LLDB 别名的 PrettyPrint JSON 解决方案

? 不需要代码

  • 要获得良好的 json 格式(缩进、换行等),您可以通过在 XCode()中的 lldb 终端中运行此命令来定义 lldb 别名:
command regex pjson 's/(.+)/expr print(NSString(string: String(data: try! JSONSerialization.data(withJSONObject: %1, options: .prettyPrinted), encoding: .utf8)!))/'
Run Code Online (Sandbox Code Playgroud)
  • 上面的命令仅在当前 XCode 会话期间有效。为避免每次打开 XCode 时都重新定义别名,请在 macOS 终端中运行以下命令。它将附加上面定义的别名,~/.lldbinit每次 XCode 启动时 LLDB 将加载到该别名:
command regex pjson 's/(.+)/expr print(NSString(string: String(data: try! JSONSerialization.data(withJSONObject: %1, options: .prettyPrinted), encoding: .utf8)!))/'
Run Code Online (Sandbox Code Playgroud)
  • 这将创建pjson您可以在 XCode 的 lldb 终端中使用的别名:
pjson object
Run Code Online (Sandbox Code Playgroud)

比较以下 Swift 对象的输出:

echo "command regex pjson 's/(.+)/expr print(NSString(string: String(data: try! JSONSerialization.data(withJSONObject: %1, options: .prettyPrinted), encoding: .utf8)!))/'" >> ~/.lldbinit
Run Code Online (Sandbox Code Playgroud)

? 输出pjson dictionary

{
  "F" : "foxtrot",
  "D" : "delta",
  "embedded" : {
    "JustForTheSakeOfTheDemo" : 42
  },
  "E" : "echo",
  "A" : "alfa",
  "C" : "charlie",
  "B" : "bravo"
}
Run Code Online (Sandbox Code Playgroud)

? 输出p dictionary

(Any?) $R0 = 7 key/value pairs {
  [0] = {
    key = "F"
    value = "foxtrot"
  }
  [1] = {
    key = "D"
    value = "delta"
  }
  [2] = {
    key = "embedded"
    value = 1 key/value pair {
      [0] = (key = "JustForTheSakeOfTheDemo", value = 42)
    }
  }
  [3] = {
    key = "E"
    value = "echo"
  }
  [4] = {
    key = "A"
    value = "alfa"
  }
  [5] = {
    key = "C"
    value = "charlie"
  }
  [6] = {
    key = "B"
    value = "bravo"
  }
}
Run Code Online (Sandbox Code Playgroud)

? 输出p (dictionary as! NSDictionary)

(NSDictionary) $R18 = 0x0000000281e89710 {
  ObjectiveC.NSObject = {
    base__SwiftNativeNSDictionaryBase@0 = {
      baseNSDictionary@0 = {
        NSObject = {
          isa = Swift._SwiftDeferredNSDictionary<Swift.String, Any> with unmangled suffix "$"
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

? 输出po dictionary

? Optional<Any>
  ? some : 7 elements
    ? 0 : 2 elements
      - key : "F"
      - value : "foxtrot"
    ? 1 : 2 elements
      - key : "D"
      - value : "delta"
    ? 2 : 2 elements
      - key : "embedded"
      ? value : 1 element
        ? 0 : 2 elements
          - key : "JustForTheSakeOfTheDemo"
          - value : 42
    ? 3 : 2 elements
      - key : "E"
      - value : "echo"
    ? 4 : 2 elements
      - key : "A"
      - value : "alfa"
    ? 5 : 2 elements
      - key : "C"
      - value : "charlie"
    ? 6 : 2 elements
      - key : "B"
      - value : "bravo"
Run Code Online (Sandbox Code Playgroud)

? 输出po print(dictionary)

Optional(["F": "foxtrot", "D": "delta", "embedded": ["JustForTheSakeOfTheDemo": 42], "E": "echo", "A": "alfa", "C": "charlie", "B": "bravo"])
Run Code Online (Sandbox Code Playgroud)


Asd*_*bal 5

您可以只使用for循环并打印每次迭代

for (key,value) in dictionary { 
    print("\(key) = \(value)")
}
Run Code Online (Sandbox Code Playgroud)

申请延期:

extension Dictionary where Key: CustomDebugStringConvertible, Value:CustomDebugStringConvertible {

    var prettyprint : String {
        for (key,value) in self {
            print("\(key) = \(value)")
        }

        return self.description
    }
}
Run Code Online (Sandbox Code Playgroud)

替代申请:

extension Dictionary where Key: CustomDebugStringConvertible, Value:CustomDebugStringConvertible {

    func prettyPrint(){
        for (key,value) in self {
            print("\(key) = \(value)")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

dictionary.prettyprint //var prettyprint
dictionary.prettyPrint //func prettyPrint
Run Code Online (Sandbox Code Playgroud)

输出(在Xcode 8 beta 2 Playground中测试):

A = alfa
B = bravo
C = charlie
D = delta
E = echo
F = foxtrot
Run Code Online (Sandbox Code Playgroud)

  • 由于已经存在`description`和`debugDescription`,因此调用var`deiteDescription`并返回格式化字符串可能更合适. (2认同)

jar*_*ora 5

将 Swift 字典转换为 json 并返回的方法是最简洁的。我使用 Facebook 的chisel,它有一个pjson命令来打印 Swift 字典。例如:

(lldb) pjson dict as NSDictionary
Run Code Online (Sandbox Code Playgroud)

这应该漂亮地打印字典。这是一种更简洁的方式来执行已经建议的操作。PS 目前,您必须将 dict 转换为 NSDictionary,因为 Objective-C 运行时不理解 Swift 词典。我已经在 chisel 上提出了一个 PR 来摆脱这个限制。

更新:我的 PR 被接受了。现在你可以使用psjson命令代替上面提到的pjson 了