Skip to content

Consider adding a function that creates a string representation of a collection similar to Scala's mkString #195

Open
@fwgreen

Description

@fwgreen

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions