Kotlin Training Program

DOWNLOAD APP

FEEDBACK

Replace

We have the built-in replace() function for Char as well as String replacements :

 fun main() {
    println("Palm down!".replace('P', 'C'))
    println("Landing on Moon".replace("Moon", "Mars"))
}
 

replace(char)

Replacing character is straight forward. We simply map the string characters, where character to be replaced is mapped to replacement. We get List<Char> after the map operation. To convert it to a String, we can use the joinToString() function ;

 fun String.replace(char: Char, replacement: Char, ignoreCase: Boolean = false): String {
    return map {
        if (it.equals(char, ignoreCase)) replacement else it
    }.joinToString("")
}
 

There are other long methods of doing the same thing.

Using StringBuilder

 fun String.replaceUsingBuilder(char: Char, replacement: Char, ignoreCase: Boolean = false): String {
    return buildString {
        this@replaceUsingBuilder.forEach {
            append(if (it.equals(char, ignoreCase)) replacement else it)
        }
    }
}
 

Using new array

 fun String.replaceUsingNewArray(char: Char, replacement: Char, ignoreCase: Boolean = false): String {
    val newArray = CharArray(length)
    forEachIndexed { index, c ->
        newArray[index] = if (c.equals(char, ignoreCase)) replacement else c
    }

    return newArray.concatToString()
}
 

replace(string)

Replace a substring involves finding the substring first. We can use the pointers approach used in indexOf() implementation to find the substring. We use StringBuilder to form the new string. On each iteration, the current character is appended to the builder. When substring is found, instead of returning the index we delete the query characters appended previously and append the replacement string.

Implementation

 fun String.replace(query: String, replacement: String, ignoreCase: Boolean = false): String {
    // Pointer for query
    var j = 0

    // Instantiate a StringBuilder for building the string
    val builder = StringBuilder()

    // Iterate over this string
    forEachIndexed { i, c ->

        // If chars at both pointers are equal (partial match), increment query pointer
        if (c.equals(query[j], ignoreCase)) j++

        // If unequal and already matched >1 chars, restart
        else if (j > 0) j = 0

        // Append current char
        builder.append(c)

        // If all chars of query matched
        if (j == query.length) {

            // Replace
            builder.delete(builder.length - query.length, builder.length)
            builder.append(replacement)

            // Reset pointer for next match
            j = 0
        }
    }

    return builder.toString()
}
 

Note :

  • When query is completely matched, we remove it from builder using the delete function. The range to be deleted is (builder.length - query.length) until builder.length