Подтвердить что ты не робот

Есть ли способ распечатать словари Swift на консоль?

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, чтобы получить его в довольно печатных словарях, где каждая пара ключ-значение занимает новую строку?

4b9b3361

Ответ 1

Вы можете использовать dump, например, если целью является проверка словаря. dump является частью стандартной библиотеки Swift.

Использование:

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

dump(dictionary)

Вывод:

введите описание изображения здесь


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:.

Ответ 2

Приведение словаря к AnyObject было для меня самым простым решением:

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

this is the console output

Для меня это легче читать, чем параметр dump, но учтите, что он не даст вам общее количество значений ключа.

Ответ 3

По решению

Для тех из вас, кто хочет видеть Dictionary как JSON без escape-последовательности в консоли, вот простой способ сделать это

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

Ответ 4

Еще один способ использования функционального программирования

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

Выход

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

Ответ 5

Для цели отладки я конвертирую Array или Dictionary в довольно печатный 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
}

Ответ 6

Я бы не стал рассматривать многие ответы, представленные здесь, в истинно симпатичном печатном формате 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.

Ответ 7

Вы можете просто использовать цикл 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):

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

Ответ 8

Для Swift 3 (и опираясь на блестящий ответ @Jalakoo), сделайте следующее расширение Dictionary:

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

затем распечатать словарь любой иерархии в довольно способом (лучше, чем dump()) с помощью этого:

print(dictionary!.prettyPrint)

Ответ 9

Методология преобразования Свифт-словаря в json и обратно является самой удобной. Я обычно использую долото Facebook, у которого есть команда pjson, чтобы напечатать словарь Swift. Например:

(lldb) pjson dict as NSDictionary

Это должно красиво распечатать словарь. Это гораздо более чистый способ сделать то, что уже было предложено. PS На данный момент вам придется использовать dict как NSDictionary, потому что среда выполнения Objective C не понимает словари Swift. Я уже поднял пиар на долоте, чтобы избавиться от этого ограничения.

Ответ 10

подробности

  • 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

Ответ 11

Как насчет:

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)

Ответ 12

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