Created
August 9, 2022 14:28
-
-
Save Kyome22/7d1dd240fe0505a4521dd398116a0b20 to your computer and use it in GitHub Desktop.
Print an object like the tree format.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
struct SwiftTree { | |
enum RuledLine { | |
static let root = "." | |
static let stem = "│ " | |
static let branch = "├──" | |
static let lastBranch = "└──" | |
static let space = " " | |
} | |
enum Parent { | |
case none | |
case array | |
case dictionary | |
} | |
static func print(_ obj: Any?) { | |
let output = SwiftTree.makeTree(obj: obj).joined(separator: "\n") | |
Swift.print(output) | |
} | |
private static func makeTree(obj: Any?, parent: Parent = .none, isLast: Bool = false, prefix: [String] = []) -> [String] { | |
var result = [String]() | |
if let dict = obj as? [String: Any?] { // Dictionay | |
let array: [(key: String, value: Any?)] = dict.sorted { $0.key < $1.key } | |
if parent == .array, array.count == 1, let first = array.first { | |
result.append(contentsOf: makeTree(obj: first.key, | |
parent: .array, | |
isLast: isLast, | |
prefix: prefix)) | |
let valuePrefix = prefix + [isLast ? RuledLine.space : RuledLine.stem] | |
result.append(contentsOf: makeTree(obj: first.value, | |
parent: .dictionary, | |
isLast: true, | |
prefix: valuePrefix)) | |
} else { | |
if parent == .none { | |
result.append(RuledLine.root) | |
} else if parent == .array { | |
result.append(contentsOf: makeTree(obj: RuledLine.root, | |
parent: .array, | |
isLast: isLast, | |
prefix: prefix)) | |
} | |
for i in (0 ..< array.count) { | |
let isLastValue: Bool = (i == array.count - 1) | |
var keyPrefix = prefix | |
if parent == .array { | |
keyPrefix.append(isLast ? RuledLine.space : RuledLine.stem) | |
} | |
result.append(contentsOf: makeTree(obj: array[i].key, | |
parent: .dictionary, | |
isLast: isLastValue, | |
prefix: keyPrefix)) | |
let valuePrefix = keyPrefix + [isLastValue ? RuledLine.space : RuledLine.stem] | |
result.append(contentsOf: makeTree(obj: array[i].value, | |
parent: .dictionary, | |
isLast: true, | |
prefix: valuePrefix)) | |
} | |
} | |
} else if let array = obj as? [Any?] { // Array | |
if array.isEmpty { | |
let isLastValue: Bool = (parent == .dictionary ? true : isLast) | |
result.append(contentsOf: makeTree(obj: "empty", | |
parent: .array, | |
isLast: isLastValue, | |
prefix: prefix)) | |
} else if parent == .array, array.count == 1, let first = array.first { | |
result.append(contentsOf: makeTree(obj: first, | |
parent: .array, | |
isLast: isLast, | |
prefix: prefix)) | |
} else { | |
if parent == .none { | |
result.append(RuledLine.root) | |
} else if parent == .array { | |
result.append(contentsOf: makeTree(obj: RuledLine.root, | |
parent: .array, | |
isLast: isLast, | |
prefix: prefix)) | |
} | |
for i in (0 ..< array.count) { | |
let isLastValue: Bool = i == (array.count - 1) | |
var valuePrefix = prefix | |
if parent == .array { | |
valuePrefix.append(isLast ? RuledLine.space : RuledLine.stem) | |
} | |
result.append(contentsOf: makeTree(obj: array[i], | |
parent: .array, | |
isLast: isLastValue, | |
prefix: valuePrefix)) | |
} | |
} | |
} else { // Element | |
let valuePrefix = prefix + [isLast ? RuledLine.lastBranch : RuledLine.branch] | |
let line = (valuePrefix + ["\(obj ?? "nil")"]).joined(separator: " ") | |
result.append(line) | |
} | |
return result | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How to use
Print Sample Object
Output