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

问题描述 投票:61回答:12
NSDictionary *dictionary = @{@"A" : @"alfa",
                             @"B" : @"bravo",
                             @"C" : @"charlie",
                             @"D" : @"delta",
                             @"E" : @"echo",
                             @"F" : @"foxtrot"};
NSLog(@"%@", dictionary.description);

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

{
    A = alfa;
    B = bravo;
    C = charlie;
    D = delta;
    E = echo;
    F = foxtrot;
}

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

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

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

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

ios swift xcode
12个回答
71
投票

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

用法:

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

dump(dictionary)

输出:

enter image description here


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

阵列的详细视图:

let names = ["Joe", "Jane", "Jim", "Joyce"]
dump(names)

打印:

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

对于字典:

let attributes = ["foo": 10, "bar": 33, "baz": 42]
dump(attributes)

打印:

▿3个键/值对 ▿[0] :( 2个元素) - .0:吧 - .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")

打印:

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

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


1
投票

细节

  • Xcode 10.2.1(10E1001),Swift 5

extension Dictionary {
    func format(options: JSONSerialization.WritingOptions) -> Any? {
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: self, options: options)
            return try JSONSerialization.jsonObject(with: jsonData, options: [.allowFragments])
        } catch {
            print(error.localizedDescription)
            return nil
        }
    }
}

用法

let dictionary: [String : Any] = [
                                    "id": 0,
                                    "bool": true,
                                    "int_array": [1,3,5],
                                    "dict_array": [
                                        ["id": 1, "text": "text1"],
                                        ["id": 1, "text": "text2"]
                                    ]
                                 ]
print("Regualr print:\n\(dictionary)\n")
guard let formatedDictionary = dictionary.format(options: [.prettyPrinted, .sortedKeys]) else { return }
print("Pretty printed:\n\(formatedDictionary)\n")

结果

enter image description here


0
投票

怎么样:

import Foundation

extension Dictionary {
    var myDesc: String {
        get {
            var v = ""
            for (key, value) in self {
                v += ("\(key) = \(value)\n")
            }
            return v
        }
    }
}


// Then, later, for any dictionary:
print(dictionary.myDesc)

0
投票
extension String {

    var conslePrintString: String {

        guard let data = "\""
            .appending(
                replacingOccurrences(of: "\\u", with: "\\U")
                    .replacingOccurrences(of: "\"", with: "\\\"")
            )
            .appending("\"")
            .data(using: .utf8) else {

            return self
        }

        guard let propertyList = try? PropertyListSerialization.propertyList(from: data,
                                                                             options: [],
                                                                             format: nil) else {
            return self
        }

        guard let string = propertyList as? String else {
            return self
        }

        return string.replacingOccurrences(of: "\\r\\n", with: "\n")
    }
}

let code in extension String and it works fine 

let string = "\(jsonDictionary)".conslePrintString

64
投票

SWIFT 3

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

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

enter image description here

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


60
投票

通过soluteion

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

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


31
投票

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

dictionary.forEach { print("\($0): \($1)") }

产量

B: bravo
A: alfa
F: foxtrot
C: charlie
D: delta
E: echo

17
投票

出于调试目的,我只将数组或字典转换为漂亮的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 "{}"
        }
    }
}

然后:

print("\nHTTP request: \(URL)\nParams: \(params.json())\n")

控制台上的结果:

HTTP request: https://example.com/get-data
Params: {
  "lon" : 10.8663676,
  "radius" : 111131.8046875,
  "lat" : 23.8063882,
  "index_start" : 0,
  "uid" : 1
}

7
投票

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

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

这是一个例子:

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

    if let jsonString = String(data: jsonData, encoding: .utf8) {
        print(jsonString)
    }

结果:

{
    "jsonData": [
        "Some String"
    ],
    "moreJSONData": "Another String",
    "evenMoreJSONData": {
        "A final String": "awd"
    }
}

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

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


5
投票

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

for (key,value) in dictionary { 
    print("\(key) = \(value)")
}

申请延期:

extension Dictionary where Key: CustomDebugStringConvertible, Value:CustomDebugStringConvertible {

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

        return self.description
    }
}

替代申请:

extension Dictionary where Key: CustomDebugStringConvertible, Value:CustomDebugStringConvertible {

    func prettyPrint(){
        for (key,value) in self {
            print("\(key) = \(value)")
        }
    }
}

用法:

dictionary.prettyprint //var prettyprint
dictionary.prettyPrint //func prettyPrint

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

A = alfa
B = bravo
C = charlie
D = delta
E = echo
F = foxtrot

4
投票

对于Swift 3(并建立在@Jalakoo的精彩回答之上),请进行以下Dictionary扩展:

extension Dictionary where Key: ExpressibleByStringLiteral, Value: Any {
    var prettyPrint: String {
        return String(describing: self as AnyObject)
    }
}

然后使用以下方法以漂亮的方式打印任何层次结构的字典(优于dump()):

print(dictionary!.prettyPrint)

2
投票

将Swift Dictionary转换为json和back的方法是最好的。我通常使用Facebook的chisel,它有一个pjson命令来打印Swift字典。例如:

(lldb) pjson dict as NSDictionary

这应该打印字典。这是一种更清洁的方式来做已经建议的事情。附:目前,您必须将dict转换为NSDictionary,因为Objective-C运行时不理解Swift词典。我已经用凿子提出了PR来摆脱这种限制。

© www.soinside.com 2019 - 2024. All rights reserved.