nth word of String (Kotlin) - kotlin

What's the simplest way to get the nth word of a String in Kotlin? I've written some code that does it (although it would currently include punctuation as part of a word), but I think there must be a much simpler way.

In the test I just printed out all elements, you can see that punctuations have been filtered out. The words is a list of string, I think you know how to get the nth element from it:
#Test
fun `extract word`() {
val input = "However, the sentence, which I am writing ... now, has words...."
val words = input.split("[.,!;\"\\s]+".toRegex())
words.forEach { println(it) }
}
Outputs:
However
the
sentence
which
I
am
writing
now
has
words

You can start with this code:
fun main() {
val sentence = "Hello, green world!"
val words = sentence.split("[,.!?\\s]+".toRegex())
val thirdWord = words[2]
println(words)
}

Maybe like this:
fun main() {
val n = 4 // 4th word
val str = "The quick brown fox jumps over the lazy dog"
val word = str.split(" ")[n-1]
println(word) // fox
}

Related

Kotlin - add a single space between string and number

I have the following texts. I need to add a single space between the string and numbers.
Text1 -> Text 1
Text10 -> Text 10
Kotlin2 -> Kotlin 2
I used the following code, but it does not work.
fun addSpace(text: String): String {
return text.split("\\D".toRegex()).joinToString(separator = " ") { it }
}
It return only the number.
You can just replace any occurrence of a string of digits with a space followed by those digits:
fun addSpace(text: String) = text.replace(Regex("\\d+" ), " \$0")
(The $ is escaped so that the Kotlin compiler doesn't treat it as interpolation.)
You can use regex groups and replaceAll
fun main() {
val input = "Text1 Text10 Kotlin2"
val pattern = Pattern.compile("([a-zA-Z]+)([0-9]+)")
val matcher = pattern.matcher(input).replaceAll("$1 $2")
println(matcher)
}
Output will be
Text 1 Text 10 Kotlin 2

Koltin - print 5(or specific Number) random CharRange '0'..'z' and using + Operator to creat one new String

I've been doing this Challage and stuck so hard.
Yes, I did find a more easy way but it doesn't fulfill the Challange condition.
Condition:
Create(Print) one String that has 5 or a specific size of Character from a CharRange using + Operator.
little example
fun main() {
val cRange: CharRange = '0'..'z'
cRange.random()
}
Functional way to generate string out of random characters
val range = 'a'..'z'
val out = generateSequence { range.random() }
.take(5)
.fold("") { acc, c -> acc + c }
This solution does not need any mutable variable

Kotlin: check if string is numeric

Is there a simple way to check if user's input is numeric? Using regexes and exceptions seems too complicated here.
fun main {
val scan = Scanner(System.`in`)
val input = scanner.nextLine()
if (!input.isNumeric) {
println("You should enter a number!")
}
}
The method mentioned above will work for a number <= approximately 4*10^18 essentially max limit of Double.
Instead of doing that since String itself is a CharSequence, you can check if all the character belong to a specific range.
val integerChars = '0'..'9'
fun isNumber(input: String): Boolean {
var dotOccurred = 0
return input.all { it in integerChars || it == '.' && dotOccurred++ < 1 }
}
fun isInteger(input: String) = input.all { it in integerChars }
fun main() {
val input = readLine()!!
println("isNumber: ${isNumber(input)}")
println("isInteger: ${isInteger(input)}")
}
Examples:
100234
isNumber: true
isInteger: true
235.22
isNumber: true
isInteger: false
102948012120948129049012849102841209849018
isNumber: true
isInteger: true
a
isNumber: false
isInteger: false
Its efficient as well, there's no memory allocations and returns as soon as any non-satisfying condition is found.
You can also include check for negative numbers by just changing the logic if hyphen is first letter you can apply the condition for subSequence(1, length) skipping the first character.
joining all the useful comments and putting it in a input stream context, you can use this for example:
fun readLn() = readLine()!!
fun readNumericOnly() {
println("Enter a number")
readLn().toDoubleOrNull()?.let { userInputAsDouble ->
println("user input as a Double $userInputAsDouble")
println("user input as an Int ${userInputAsDouble.toInt()}")
} ?: print("Not a number")
}
readNumericOnly()
for input: 10
user input as a Double 10.0
user input as an Int 10
for input: 0.1
user input as a Double 0.1
user input as an Int 0
for input: "word"
Not a number
Simply use : text.isDigitsOnly() in kotlin.
Well all the answers here are best suited for their own scenarios:
But not all string are numeric digits it can have (-) and (.) decimal pointers.
So to accomplish this I made a cocktail of all the answers suggested below and from other posts as well which - looks like below :
fun isPosOrNegNumber(s: String?) : Boolean {
return if (s.isNullOrEmpty()) false
else{
if(s.first()=='-' && s.filter { it == '.' }.count() <= 1) {
s.removeRange(0,1).replace(".","").all{Character.isDigit(it)}
}
else s.all {Character.isDigit(it)}
}
}
Above code does a good job for its purpose.
But then it struck me kotlin does an even better job with matching a regex and voila the solution became simple and elegant as below :
fun isPosOrNegNumber(s: String?) : Boolean {
val regex = """^(-)?[0-9]{0,}((\.){1}[0-9]{1,}){0,1}$""".toRegex()
return if (s.isNullOrEmpty()) false
else regex.matches(s)
}
This sample regex is only for US number formats but if you want to use EU number formats then just replace '.' with ','
Bdw. if the numbers contain commas then just replace it while sending to this method or better form a regex pattern with commas in it.
Another way to check if the given string is numeric( to check for both negative and positive values ) or not:
val intChars = '0'..'9'
fun isNumeric(input: String) = input
.removePrefix("-")
.all { it in '0'..'9' }
A simple answer without any custom functions is to utilise toDoubleOrNull function. If it returns null, the string is not numeric.
val string = "-12345.666"
if (string.toDoubleOrNull()!=null) // string is numeric
{
//do something
}
If you know the input only contains integers you can also use toIntOrNull likewise

Show or hide decimals

I have a double value, if that number is like this: 123.00 I need to show it as 123 only, without decimal places, but, if the number is like 123.23 or 123.2, I need to show it with the present decimal places: 123.23 or 123.2, as the case may be.
I have tried with decimal format but I couldn't find the right pattern.
It is a better way to do this than a string conversion and operate with substrings and things like that?
DecimalFormat is what you're looking for I think:
import java.text.DecimalFormat
fun main(args : Array<String>) {
val df = DecimalFormat("0.##")
println(df.format(123.0))
println(df.format(123.3))
println(df.format(123.32))
println(df.format(123.327))
}
Output:
123
123.3
123.32
123.33
Here's one way you could do it:
fun func(x: Double): String {
if (x.rem(1).compareTo(0) == 0){
return x.toInt().toString();
} else {
return x.toString();
}
}
print(func(1.32132)); //Returns 1.32132
print(func(3.00)); //Returns 3
You could use DecimalFormat with setMaximumFractionDigits. Creating an extension function would keep the complexity away from the call-site:
fun Double.toStringRounded(fracDigits: Int) = DecimalFormat().apply {
setMaximumFractionDigits(fracDigits)
}.format(this)
Usage:
3.14159.toStringRounded(2) // will be "3.14"

How to create String with certain length and same value effectively in Kotlin

I knew this can be achieved with for loop but I am looking for better solution.
createDummyString(1,'A') = 'A'
createDummyString(2.'A') = 'AA'
This will be used in hangman. Thank you.
You can do it like in the example below. To learn more about Strings read this: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html
fun createDummyString(repeat : Int, alpha : Char) = alpha.toString().repeat(repeat)
Addendum:
If you want to make it more kotlinesque, you can also define repeat as extension function on Char
fun Char.repeat(count: Int): String = this.toString().repeat(count)
and call it like this:
'A'.repeat(1)
CharSequence has an extension method for this.
fun CharSequence.repeat(n: Int): String // for any whole number
Example
println("A".repeat(4)) // AAAA
println("A".repeat(0)) // nothing
println("A".repeat(-1)) // Exception
Reference : https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/repeat.html
I created a utility function using infix operator for this :
infix fun Int.times(s : CharSequence): CharSequence{
return s.repeat(this)
}
//Use like val twoAs = 2 times "A"
println(a) // AA