Home > Software design >  How to extract separate capitals and numbers from String
How to extract separate capitals and numbers from String

Time:08-03

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"
            }
        }
    }
})
  • Related