Skip to content

List Converter — Swift source

Transform a list between separators (newline, comma, space, pipe, semicolon, tab) with trim, dedupe, sort, and empty-removal options. Runs entirely in your browser, with a shareable link.

This is the Swift implementation — the same logic the interactive tool runs, in a shareable, citable form.

// List Converter — split/trim/dedup/sort/join between separators — Swift port of the list-converter tool.

import Foundation

enum ListConverter {
    // Resolve a TS-style separator name to its glue; unknown names pass
    // through as a literal separator (the TS resolveSep behavior).
    static func resolveSep(_ name: String) -> String {
        switch name {
        case "newline": return "\n"
        case "comma": return ","
        case "space": return " "
        case "pipe": return "|"
        case "semicolon": return ";"
        case "tab": return "\t"
        default: return name
        }
    }

    // Options mirror the TS ListOptions; defaults are from=newline, to=comma.
    struct Options {
        var from = "newline"
        var to = "comma"
        var trim = false
        var removeEmpty = false
        var unique = false
        var sort = false
        var caseInsensitive = false
    }

    // Convert a list between separators: split -> (trim) -> (drop empties) ->
    // (dedup, first occurrence wins) -> (stable sort) -> join. Mirrors the Go twin.
    static func convert(_ input: String, options: Options = Options()) -> String {
        let o = options
        var items = input.components(separatedBy: resolveSep(o.from))
        let to = resolveSep(o.to)

        if o.trim {
            items = items.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
        }
        if o.removeEmpty {
            items = items.filter { !$0.isEmpty }
        }
        if o.unique { // seen holds keys only; items keep their original casing
            var seen = Set<String>()
            items = items.filter {
                seen.insert(o.caseInsensitive ? $0.lowercased() : $0).inserted
            }
        }
        if o.sort {
            // Swift's sort is not guaranteed stable, so enumerated() makes
            // equal keys tie-break on their original index.
            items = items.enumerated()
                .sorted { a, b in
                    let ka = o.caseInsensitive ? a.element.lowercased() : a.element
                    let kb = o.caseInsensitive ? b.element.lowercased() : b.element
                    return (ka, a.offset) < (kb, b.offset)
                }
                .map(\.element)
        }
        return items.joined(separator: to)
    }
}

// "b\n a \nB\na\n\nc" -> trim, drop empties, case-insensitive dedup+sort
var o = ListConverter.Options()
o.trim = true
o.removeEmpty = true
o.unique = true
o.sort = true
o.caseInsensitive = true
print(ListConverter.convert("b\n a \nB\na\n\nc", options: o)) // a,b,c

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →