I have 2 strings 67 Paris St. Abbeville
and 344 Paris Main Hgw
and I need to extract separately numbers so Ill have something var onlyNumbers = "67,344"
and separate capitals like var capitals = "Paris St. Abbeville,Paris Main Hgw"
How to filter capitals separate from numbers in those strings?
CodePudding user response:
I suppose you have this
val address1 = "67 Paris St. Abbeville"
val address2 = "344 Paris Main Hgw"
Simple version
If you want a string with only numbers and one without, you can use :
val address1Digits = address1.filter(Char::isDigit) // Variant 1
val address2Digits = address2.filter { it.isDigit() } // Variant 2
val address1WithoutDigits = address1.filterNot(Char::isDigit).trim() // Variant 1
val address2WithoutDigits = address2.filterNot { it.isDigit() }.trim() // Variant 2
Then you can join the result in a comma-separated string :
val address1Digits = address1.filter(Char::isDigit) // Variant 1
val address2Digits = address2.filter { it.isDigit() } // Variant 2
val onlyNumbers = "$address1Digits,$address2Digits" // "67,344"
val capitals = "$address1WithoutDigits,$address2WithoutDigits" // "Paris St. Abbeville,Paris Main Hgw"
"Complex" version
This will do "123abc456"
-> "123456"
and "abc"
But if what you want an array with all the different numbers (for example "123abc456"
-> ["123", "456"]
) you can use :
val address1Digits = address1.split("\\D ".toRegex()).filter { it.isNotEmpty() }
val address2Digits = address2.split("\\D ".toRegex()).filter { it.isNotEmpty() }
val address1WithoutDigits = address1.split("[^\\D] ".toRegex()).map(String::trim).filter { it.isNotEmpty() } // Variant 1
val address2WithoutDigits = address1.split("[^\\D] ".toRegex()).map { it.trim() }.filter { it.isNotEmpty() } // Variant 2
Again you can join results
val onlyNumbers = (address1Digits address2Digits).joinToString(",") // "67,344"
val capitals = (address1WithoutDigits address2WithoutDigits).joinToString(",") // "Paris St. Abbeville,Paris Main Hgw"
CodePudding user response:
Given test data from question, test is passing with the following code.
import io.kotest.core.spec.style.BehaviorSpec
import io.kotest.matchers.shouldBe
class AddressesTest : BehaviorSpec({
given("a list of addresses") {
val addresses = listOf("67 Paris St. Abbeville", "344 Paris Main Hgw")
`when`("split") {
val result = addresses.fold(
Pair(mutableListOf<String>(), mutableListOf<String>())
) { acc, currAddress ->
acc.apply {
currAddress.indexOf(' ').also { indexOfFirstSpace ->
/** add number part of address to first list */
first.add(currAddress.substring(0, indexOfFirstSpace))
/** add remaining part to second list */
second.add(currAddress.substring(indexOfFirstSpace 1))
}
}
}.let {
/** convert both lists to comma-delimited string */
Pair(
it.first.joinToString(","),
it.second.joinToString(",")
)
}
then("result should be as expected") {
result.first shouldBe "67,344"
result.second shouldBe "Paris St. Abbeville,Paris Main Hgw"
}
}
}
})