Consider adding a function that creates a string representation of a collection similar to Scala's mkString
fwgreen opened this issue · 0 comments
fwgreen commented
Motivation:
I wanted to pretty print a 2D array (a Sudoku board) and found mapping to string and using joined(by:)
fell short of what I needed.
let input = [
[5,3,0, 0,7,0, 0,0,0],
[6,0,0, 1,9,5, 0,0,0],
[0,9,8, 0,0,0, 0,6,0],
[8,0,0, 0,6,0, 0,0,3],
[4,0,0, 8,0,3, 0,0,1],
[7,0,0, 0,2,0, 0,0,6],
[0,6,0, 0,0,0, 2,8,0],
[0,0,0, 4,1,9, 0,0,5],
[0,0,0, 0,8,0, 0,7,9],
]
/*
+-------+-------+-------+
| 5 3 0 | 0 7 0 | 0 0 0 |
| 6 0 0 | 1 9 5 | 0 0 0 |
| 0 9 8 | 0 0 0 | 0 6 0 |
+-------+-------+-------+
| 8 0 0 | 0 6 0 | 0 0 3 |
| 4 0 0 | 8 0 3 | 0 0 1 |
| 7 0 0 | 0 2 0 | 0 0 6 |
+-------+-------+-------+
| 0 6 0 | 0 0 0 | 2 8 0 |
| 0 0 0 | 4 1 9 | 0 0 5 |
| 0 0 0 | 0 8 0 | 0 7 9 |
+-------+-------+-------+
*/
My current solution is to copy Scala's mkString
but I wonder if there is a better (more general and performant) way:
extension Collection {
func makeString(_ separator: String) -> String { makeString("", separator, "") }
func makeString(_ prefix: String, _ separator: String, _ suffix: String) -> String {
if isEmpty {
return prefix + suffix
} else {
return addString("", prefix, separator, suffix)
}
}
private func addString(_ string: String, _ prefix: String, _ separator: String, _ suffix: String) -> String {
var string = string
if prefix.count != 0 { string.append(contentsOf: prefix) }
var it = makeIterator()
if let start = it.next() {
string.append(contentsOf: "\(start)")
while let rest = it.next() {
string.append(contentsOf: separator)
string.append(contentsOf: "\(rest)")
}
}
if suffix.count != 0 { string.append(contentsOf: suffix) }
return string
}
}
//This allows for something close to what is possible in Scala
func prettyString(_ sudoku: [[Int]]) -> String {
sudoku.chunks(ofCount: 3).map { bigChunck in
bigChunck.map { row in
row.chunks(ofCount: 3).map { smallChunk in
smallChunk.makeString(" ", " ", " ")
}.makeString("|", "|", "|")
}.makeString("\n")
}.makeString("+-------+-------+-------+\n", "\n+-------+-------+-------+\n", "\n+-------+-------+-------+")
}