How to remove duplicate case‑insensitive words separated by multiple delimiters from a string in Swift

1 Answer

0 votes
import Foundation

/*
    Remove duplicate case‑insensitive words separated by multiple delimiters.

    Features:
    - Case‑insensitive comparison (lowercased())
    - Preserves original casing of the first occurrence
    - Trims whitespace around tokens
    - Supports ANY number of delimiters (including multi‑character)
    - Preserves original order
    - Efficient O(n) lookup using Set<String>
*/

/* ---------------------------------------------------------------
   Build a regex that matches ANY delimiter
--------------------------------------------------------------- */
func buildDelimiterRegex(_ delimiters: [String]) -> Regex<AnyRegexOutput> {
    // Escape delimiters so characters like "|" or "*" are treated literally
    let escaped = delimiters.map { NSRegularExpression.escapedPattern(for: $0) }

    // Combine into one regex: (delim1|delim2|...)
    let pattern = "(?:\(escaped.joined(separator: "|")))+"

    return try! Regex(pattern)
}

/* ---------------------------------------------------------------
   Split input string using multiple delimiters
--------------------------------------------------------------- */
func splitByDelimiters(_ input: String, _ delimiters: [String]) -> [String] {
    let regex = buildDelimiterRegex(delimiters)

    return input
        .split(separator: regex)
        .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
        .filter { !$0.isEmpty }
}

/* ---------------------------------------------------------------
   Remove duplicates (case‑insensitive)
--------------------------------------------------------------- */
func removeDuplicatesCaseInsensitive(_ tokens: [String]) -> [String] {
    var seen = Set<String>()
    var unique = [String]()

    for token in tokens {
        let key = token.lowercased()
        if !seen.contains(key) {
            seen.insert(key)
            unique.append(token)
        }
    }

    return unique
}

/* ---------------------------------------------------------------
   Join tokens with a chosen delimiter
--------------------------------------------------------------- */
func joinTokens(_ tokens: [String], _ delimiter: String) -> String {
    tokens.joined(separator: delimiter)
}

/* ---------------------------------------------------------------
   Main function
--------------------------------------------------------------- */
func removeDuplicatesMultiDelimiterCI(
    _ input: String,
    _ delimiters: [String],
    _ outputDelimiter: String
) -> String {
    let tokens = splitByDelimiters(input, delimiters)
    let unique = removeDuplicatesCaseInsensitive(tokens)
    return joinTokens(unique, outputDelimiter)
}

/* ---------------------------------------------------------------
   Main
--------------------------------------------------------------- */

let s =
    "AAA | aaa ,   aAA * aaA | AAa | AAA   | BBB | ccc ---- CCC | AAA ; aaa | bbb"

let delimiters = ["  ", "|", ",", "*", "-", ";"]

let result = removeDuplicatesMultiDelimiterCI(s, delimiters, " | ")

print(result)



/*
run:

AAA | BBB | ccc

*/

 



answered Aug 2 by avibootz

Related questions

...