I suggest table-style printing for 2D arrays, dictionaries, and tuples. Inspired from Javascript console.table
The stdlib print doesn't support table-style output. So It is hard to check the data in the 2D array.
Here is my suggestion. I made a sample project called Table.
1D Array with Header
print(
table: ["Good", "Very Good", "Happy", "Cool!"],
header: ["Wed", "Thu", "Fri", "Sat"]
)
Output:
+----+---------+-----+-----+
|Wed |Thu |Fri |Sat |
+----+---------+-----+-----+
|Good|Very Good|Happy|Cool!|
+----+---------+-----+-----+
2D Array but the length of data is not equal.
print(
table: [["1", "b2"],
["Hellow", "Great!"],
["sdjfklsjdfklsadf", "dsf", "1"]]
)
OUtput:
+----------------+------+-+
|1 |b2 | |
+----------------+------+-+
|Hellow |Great!| |
+----------------+------+-+
|sdjfklsjdfklsadf|dsf |1|
+----------------+------+-+
Dictionary
print(
table: [
"1": 1,
2: "Hellow?",
1.2: 0,
"I'm Table": [1, 2, 3, 2, 1]
],
header: ["key", "value"]
)
Output
+---------+---------------+
|key |value |
+---------+---------------+
|2 |Hellow? |
+---------+---------------+
|I'm Table|[1, 2, 3, 2, 1]|
+---------+---------------+
|1.2 |0 |
+---------+---------------+
|1 |1 |
+---------+---------------+
Implementation
- Define the print function.
public enum TableSpacing {
case fillProportionally
case fillEqually
}
/// - Parameters:
/// - table: Zero or more items to print.
/// - header: A string to print header on table.
/// - terminator: A string to print end of function.
/// - distribution: A spacing for item
@discardableResult public func print(
table data: Any,
header: [String]? = nil,
distribution: TableSpacing = .fillProportionally,
terminator: String = ""
) -> String
- Check the table type
let mirrorObj = Mirror(reflecting: data)
if mirrorObj.subjectType == [String].self {
}
else if mirrorObj.subjectType == [Int].self {
}
else if else if mirrorObj.subjectType == [AnyHashable: Any].self {
}
...
- Helper functions
- 3.1 Horizontal Line
Use for drawing the horizontal line on Table
@discardableResult private func horizontal(
numberOfItems: Int,
keyWidth: Int,
valueWidth: Int,
distribution: TableSpacing
) -> String
- 3.2 Table Infomation
Calculating the spaces between the data
private func tableInfo(data: [AnyHashable: Any]) -> (
numberOfItem: Int,
maxKeyWidth: Int,
maxValueWidth: Int,
widthInfo: [String: Int]
)
private func tableInfo<Item: LosslessStringConvertible>(data: [Item]) -> (
numberOfItem: Int,
maxWidth: Int,
widthInfo: [Int: Int]
)
private func tableInfo<Item: LosslessStringConvertible>(data: [[Item]]) -> (
numberOfItem: Int,
maxWidth: Int,
widthInfo: [Int: Int]
)
Unit Test
func test_1DArray_Of_String_with_header() {
let output = print(
table: ["Good", "Very Good", "Happy", "Cool!"],
header: ["Wed", "Thu", "Fri", "Sat"]
)
let expected = """
+----+---------+-----+-----+
|Wed |Thu |Fri |Sat |
+----+---------+-----+-----+
|Good|Very Good|Happy|Cool!|
+----+---------+-----+-----+
"""
XCTAssertEqual(output, expected)
}
func test_1DArray_Of_Int() {
let output = print(table: [2, 94231, 241245125125])
let expected = """
+-+-----+------------+
|2|94231|241245125125|
+-+-----+------------+
"""
XCTAssertEqual(output, expected)
}
func test_1DArray_Of_Double() {
let output = print(table: [2.0, 931, 214.24124])
let expected = """
+---+-----+---------+
|2.0|931.0|214.24124|
+---+-----+---------+
"""
XCTAssertEqual(output, expected)
}
func test_2DArray_Of_String() {
let output = print(
table: [["1", "HELLOW"], ["2", "WOLLEH"]],
header: ["Index", "Words"]
)
let expected = """
+-----+------+
|Index|Words |
+-----+------+
|1 |HELLOW|
+-----+------+
|2 |WOLLEH|
+-----+------+
"""
XCTAssertEqual(output, expected)
}
func test_2DArray_Of_String_With_Different_Columns() {
let output = print(
table: [["1", "b2"], ["Hellow", "Great!"], ["sdjfklsjdfklsadf", "dsf", "1"]],
header: ["1", "2", "3"]
)
let expected = """
+----------------+------+-+
|1 |2 |3|
+----------------+------+-+
|1 |b2 | |
+----------------+------+-+
|Hellow |Great!| |
+----------------+------+-+
|sdjfklsjdfklsadf|dsf |1|
+----------------+------+-+
"""
XCTAssertEqual(output, expected)
}
func test_2DArray_Of_Int_With_Different_Columns() {
let output = print(table: [[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]])
let expected = """
+-+-+-+--+
|1|2|3| |
+-+-+-+--+
|4|5|6| |
+-+-+-+--+
|7|8|9|10|
+-+-+-+--+
"""
XCTAssertEqual(output, expected)
}
func test_fillEqually_for_1DArray_Of_String_with_header() {
let output = print(
table: ["Good", "Very Good", "Happy", "Cool!"],
header: ["Wed", "Thu", "Fri", "Sat"],
distribution: .fillEqually
)
let expected = """
+---------+---------+---------+---------+
|Wed |Thu |Fri |Sat |
+---------+---------+---------+---------+
|Good |Very Good|Happy |Cool! |
+---------+---------+---------+---------+
"""
XCTAssertEqual(output, expected)
}
func test_fillEqually_for_1DArray_Of_Int() {
let output = print(
table: [2, 94231, 241245125125],
distribution: .fillEqually
)
let expected = """
+------------+------------+------------+
|2 |94231 |241245125125|
+------------+------------+------------+
"""
XCTAssertEqual(output, expected)
}
func test_fillEqually_for_1DArray_Of_Double() {
let output = print(
table: [2.0, 931, 214.24124],
distribution: .fillEqually
)
let expected = """
+---------+---------+---------+
|2.0 |931.0 |214.24124|
+---------+---------+---------+
"""
XCTAssertEqual(output, expected)
}
func test_fillEqually_for_2DArray_Of_String() {
let output = print(
table: [["1", "HELLOW"], ["2", "WOLLEH"]],
header: ["Index", "Words"],
distribution: .fillEqually
)
let expected = """
+------+------+
|Index |Words |
+------+------+
|1 |HELLOW|
+------+------+
|2 |WOLLEH|
+------+------+
"""
XCTAssertEqual(output, expected)
}
func test_fillEqually_for_2DArray_Of_String_With_Different_Columns() {
let output = print(
table: [["1", "b2"], ["Hellow", "Great!"], ["sdjfklsjdfklsadf", "dsf", "1"]],
header: ["1", "2", "3"],
distribution: .fillEqually
)
let expected = """
+----------------+----------------+----------------+
|1 |2 |3 |
+----------------+----------------+----------------+
|1 |b2 | |
+----------------+----------------+----------------+
|Hellow |Great! | |
+----------------+----------------+----------------+
|sdjfklsjdfklsadf|dsf |1 |
+----------------+----------------+----------------+
"""
XCTAssertEqual(output, expected)
}
func test_fillEqually_for_2DArray_Of_Int_With_Different_Columns() {
let output = print(
table: [[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]],
distribution: .fillEqually
)
let expected = """
+--+--+--+--+
|1 |2 |3 | |
+--+--+--+--+
|4 |5 |6 | |
+--+--+--+--+
|7 |8 |9 |10|
+--+--+--+--+
"""
XCTAssertEqual(output, expected)
}