ios 有没有办法将 Swift 字典漂亮地打印到控制台?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38773979/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:51:26  来源:igfitidea点击:

Is there a way to pretty print Swift dictionaries to the console?

iosswiftxcode

提问by Toland Hon

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

prints out the following on the console:

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

{
    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)

prints out the following on the console:

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

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

Is there a way in Swift to get it to pretty print dictionaries where each key-value pair occupies a new line?

Swift 中有没有办法让它打印出漂亮的字典,其中每个键值对都占据一个新行?

回答by Jalakoo

Casting a dictionary to 'AnyObject' was the simplest solution for me:

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

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

this is the console output

这是控制台输出

This is easier to read for me than the dump option, but note it won't give you the total number of key-values.

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

回答by Irshad Mohamed

po solution

溶液

For those of you want to see Dictionary as JSON with out escape sequence in console, here is a simple way to do that

对于那些希望在控制台中将 Dictionary 视为没有转义序列的 JSON 的人,这里有一个简单的方法来做到这一点

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

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

回答by Eric Aya

You could use dump, for example, if the goal is to inspect the dictionary. dumpis part of Swift's standard library.

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

Usage:

用法:

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

dump(dictionary)

Output:

输出:

enter image description here

在此处输入图片说明



dumpprints the contents of an object via reflection (mirroring).

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

Detailed view of an array:

数组的详细视图:

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

Prints:

印刷:

? 4 elements
- [0]: Joe
- [1]: Jane
- [2]: Jim
- [3]: Joyce

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

For a dictionary:

对于字典:

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

Prints:

印刷:

? 3 key/value pairs
? [0]: (2 elements)
- .0: bar
- .1: 33
? [1]: (2 elements)
- .0: baz
- .1: 42
? [2]: (2 elements)
- .0: foo
- .1: 10

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

dumpis declared as dump(_:name:indent:maxDepth:maxItems:).

dump被声明为dump(_:name:indent:maxDepth:maxItems:).

The first parameter has no label.

第一个参数没有标签。

There's other parameters available, like nameto set a label for the object being inspected:

还有其他可用的参数,例如name为正在检查的对象设置标签:

dump(attributes, name: "mirroring")

Prints:

印刷:

? mirroring: 3 key/value pairs
? [0]: (2 elements)
- .0: bar
- .1: 33
? [1]: (2 elements)
- .0: baz
- .1: 42
? [2]: (2 elements)
- .0: foo
- .1: 10

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

You can also choose to print only a certain number of items with maxItems:, to parse the object up to a certain depth with maxDepth:, and to change the indentation of printed objects with indent:.

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

回答by Luca Angeletti

Just another way using Functional Programming

使用函数式编程的另一种方式

dictionary.forEach { print("\(
B: bravo
A: alfa
F: foxtrot
C: charlie
D: delta
E: echo
): \()") }

Output

输出

public extension Collection {

    /// Convert self to JSON String.
    /// Returns: the pretty printed JSON string or an empty string if any error occur.
    func json() -> String {
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: self, options: [.prettyPrinted])
            return String(data: jsonData, encoding: .utf8) ?? "{}"
        } catch {
            print("json serialization error: \(error)")
            return "{}"
        }
    }
}

回答by Marco M

For debug purpose only I would convert the Array or Dictionary to a pretty printed json:

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

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

Then:

然后:

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

Result on console:

控制台结果:

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

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

回答by James Wolfe

I wouldn't consider a lot of the answers provided here true pretty printed JSON, as when you pass the results into a JSON validator the result is invalid (often due to the code including '=' rather than ':').

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

The easiest way I've found of doing this is just converting the JSON object to data using the pretty printed writing option then printing a string using the resulting data.

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

Here is an example:

下面是一个例子:

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

Result:

结果:

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

EDIT: It's been pointed out that the OP did not ask for JSON, however I find that the answers that recommend just printing or dumping the data into the console provide very little formatting (if any) and are therefore not pretty printing.

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

I believe that despite the OP not asking for JSON, it is a viable answer as it is a much more readable format for data than the horrendous format that is spat out into the console by xcode/swift.

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

回答by Asdrubal

You can just use a for loop and print each iteration

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

extension Dictionary where Key: CustomDebugStringConvertible, Value:CustomDebugStringConvertible {

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

        return self.description
    }
}

Application in extension:

在扩展中的应用:

extension Dictionary where Key: CustomDebugStringConvertible, Value:CustomDebugStringConvertible {

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

Alternate application:

替代应用:

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

Usage:

用法:

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

Output (Tested in Xcode 8 beta 2 Playground):

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

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

回答by AbdelHady

For Swift 3(& building on the brilliant answer by @Jalakoo), make the following Dictionaryextension:

对于Swift 3(并以@Jalakoo的精彩回答为基础),进行以下Dictionary扩展:

print(dictionary!.prettyPrint)

then print a dictionary of any hierarchyin a prettyway (better than dump()) using this:

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

(lldb) pjson dict as NSDictionary

回答by jarora

The methodology of converting the Swift Dictionary to json and back is the neatest. I use Facebook's chiselwhich has a pjsoncommand to print a Swift dictionary. Eg:

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

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
        }
    }
}

This should pretty-print the dictionary. This is a much cleaner way to do what has already been suggested. P.S. For now, you'll have to cast dict as NSDictionary because Objective-C runtime doesn't understand Swift dictionaries. I have already raised a PR on chisel to get rid of that restriction.

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

UPDATE:My PR got accepted. Now you can use psjsoncommand instead of pjsonmentioned above.

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

回答by Vasily Bodnarchuk

Details

细节

  • Xcode 10.2.1 (10E1001), Swift 5
  • Xcode 10.2.1 (10E1001),Swift 5

Solution

解决方案

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")

Usage

用法

##代码##

Results

结果

enter image description here

在此处输入图片说明