In Kotlin how to parse a double or float number from string like this:
var st: String? = "90 min"
tried to use toDoubleOrNull but always returns 0 or null.
If you are certain that the number is always at the start, then use split() with space as delimiter and from the returned list take the 1st item and parse it to Double:
val value = st!!.split(" ")[0].toDoubleOrNull()
If there is a case of spaces at the start or in between, use this:
val value = st!!.trim().split("\\s+".toRegex())[0].toDoubleOrNull()
And another way with substringBefore():
val value = st!!.trim().substringBefore(" ").toDoubleOrNull()
Or if there is only 1 integer number in the string, remove every non numeric char with replace():
val value = st!!.replace("\\D".toRegex(), "").toDoubleOrNull()
You can try (assuming you have only one sequence of numbers in your string).
Otherwise, check other answers
val inputString = "123. Test"
val regex = "\\d+(\\.\\d+)?".toRegex()
val match = regex.find(inputString)
if (match != null) {
println("Result: " + match.value)
} else {
println("Result: Not found")
}
This should work...
val pattern = Pattern.compile("\\d+") // the regex
val matcher = pattern.matcher("hello123hgj") // your string
val doubles = ArrayList<Double>() // results
while (matcher.find())
{ // for each match
doubles.add(Double.parseDouble(matcher.group())) // convert to double
}
It depends on what you need. If you just have to get 90 and the string is formatted always in the same way you can just
var string = "90 min"
var floatFromString = string.substring(0,2).toFloat()
but it's better to learn how to use LocalDate and DateTimeFormatter
Related
}
ConvertButton.setOnClickListener {
val amount = amountEt.text.toString().toDouble()
val tofield = values[Tomune.text.toString()]
val fromfield = values[from_menu.text.toString()]
var result = amount * (tofield!!.div( fromfield!!)) // error apper when i use .div() or / sign
showentext.setText(result.toString())
}
}
val tofield = values[Tomune.text.toString()] Tomune.text.toString() is a string you have not converted it to a int. Hence you are trying to access the values array by the string which is probably returning you a value that you can't divide
How can we split a text between two char in Kotlin?
Example string:
base_id:94, user_id: 320903, is_Active=1
I want to get only user_id so "320903". But I couldn't do that.
One way to get it is using regex and you can customize it to cover base_id and is_Active
val pattern = Pattern.compile("user_id: (?<id>[0-9]+)")
val matcher = pattern.matcher(text)
if (matcher.find()) {
val group = matcher.group("id").trim()
println(group)
}
The output will be : 320903
Or you can do that with split only and you will get the same result
val items = text.split(",")
val userId = items[1].split(":")[1].trim()
println(userId)
That will work correctly with your example but make sure but for other cases, you may need to customize it or give us many examples to cover them
You can handle the 3 values with one function that support optional whitespace and : or =
fun getValueByTagName(text : String, tag : String) : String {
val pattern = Pattern.compile("$tag[:=][ ]*(?<id>[0-9]+)")
val matcher = pattern.matcher(text)
return if (matcher.find())
matcher.group("id").trim()
else ""
}
To use it
println(getValueByTagName(text, "base_id")) // 94
println(getValueByTagName(text, "user_id")) // 320903
println(getValueByTagName(text, "is_Active")) // 1
Another solution:
Method 1: If your string has exactly the same format that you have shown in the example.
val indexOfUserId = s.indexOf("user_id") // find index of the substring "user_id"
val end = s.indexOf(',', indexOfUserId) // find index of ',' after user_id
val userId s.substring(indexOfUserId + 9, end) // take the substring assuming that userId starts exactly 9 characters after the "u" in "user_id"
Method 2: If your format can vary (in spaces and symbols). Also assuming that user_id is always a number.
val indexOfUserId = s.indexOf("user_id")
val start = s.findAnyOf(List(10) { "$it" }, indexOfUserId)!!.first // find the first digit after "user_id"
val userId = s.substring(start).takeWhile { it.isDigit() } // start from the first digit and continue as long as you are getting digits
Here, List(10) { "$it" } is just a list of all digits in string format and findAnyOf:
Finds the first occurrence of any of the specified [strings] in this char sequence, starting from the specified [startIndex]
Try it yourself
I'm wondering is there some method or methods combo that could obtain these results.
What I meant is that you have a string ex. "Hello world, how are you?"
And I want to achieve following functionality, to get start and end index of substring
in that string.
ex. substring = "world", and start index would be 6, and end index 10
Is there something like this in standard kotlin libraries?
Something like this?
val s = "Hi there"
val substringToFind = "there"
val start = s.indexOf(substringToFind)
val end = start + substringToFind.length
println(s.substring(start,end))
output: there
Maybe you could just use indexOf assuming you just want the first occurence:
fun main(args: Array<String>) {
val str = "Hello world, how are you?"
val sub = "world"
println(getStartAndEndOfSubstring(str, sub))
}
fun getStartAndEndOfSubstring(str: String, sub: String): Pair<Int, Int> {
val start = str.indexOf(sub)
when (start != -1) {
true -> return Pair(start, start + sub.length - 1)
false -> return Pair(-1, -1)
}
}
Output:
(6, 10)
I made a simple program to learn about concatenation in android studio with Kotlin. So, I tried to get a string value from resources in strings.xml as shown below and concatenate with a value
<string name="txt_show">Your lucky number is %1$s</string>
I got warning "Do not concatenate text..." from getString
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val firstNumber = numEditText.text
processButton.setOnClickListener {
val result = concatText(firstNumber.toString().toDouble())
resultView.text = getString(R.string.txt_show, " ") + result.format(2)
}
}
private fun concatText(myNumber: Double): Double {
val luckyNumber = 1.79
return luckyNumber * myNumber
}
private fun Double.format(digits: Int) = java.lang.String.format("%.${digits}f", this)}
By replacing
resultView.text = getString(R.string.txt.show, " ") + result.format(2)
with
val finalResult = result.toInt()<p>
resultView.text = getString(R.string.txt_show, finalResult)<p>
And replace %1$s to %1$d in resources of strings.xml
The warning is gone but I got problems, first the result is integer which is not what I expected. It should be double. Second, adding the function format in getString will stop the program with "Unexpected Error..." message on the screen.
How can I solve this problem?
If you have string with some placeholders like:
<string name="price_string">Your price: %d</string>
First you have to read this value and next fill it
JAVA
String text = getString(R.string.price_string, 2.5);
KOTLIN
val text = getString(R.string.price_string, 2.5)
.
or in "longer" way:
JAVA:
// Read text
String priceString = getString(R.string.price_string);
// Fill it
String output = String.format(priceString, 2.5);
KOTLIN
// Read text
val priceString = getString(R.string.price_string)
// Fill it
val output = String.format(priceString, 2.5)
// or
val output = priceString.format(2.5)
If you have %s you have to fill it with String. Here you have more info: https://developer.android.com/guide/topics/resources/string-resource#formatting-strings
first the result is integer which is not what I expected. It should be double.
Then why did you call toInt? Just use
resultView.text = getString(R.string.txt_show, result)
and %1$.2f (or just %.2f) in the string instead of %1$d to format to two digits fractional number. You can see it's specified the same as in the format function in your code. The documentation for format strings (what all of these %d etc. mean) is at https://developer.android.com/reference/java/util/Formatter.html.
I have a model that contains some field. I wanna sort this model before a show in recycler by sorted title. my title contains number into a string in some part like session 1 - episode 22. I use this algorithm for sort number in string type with two-digits like episode 22.
sortData.toObservable()
.sorted { o1, o2 ->
val pattern = Pattern.compile("\\d+")
val matcher = pattern.matcher(o1.title)
val matcher2 = pattern.matcher(o2.title)
if (matcher.find()) {
val isFind = matcher2.find()
val o1Num = matcher.group(0).toInt()
val o2Num = if (isFind) {
matcher2.group(0).toInt()
} else {
o1Num + 1
}
return#sorted o1Num - o2Num
} else {
return#sorted o1.title?.compareTo(o2.title ?: "") ?: 0
}
}
.toList()
.subscribeBy(
onError = {
it
},
onSuccess = {
sortData = it
}
)
my problem with this algorithm is when my title contains just simple format like episode 22 and just digits are between 0-99 it's work good but when I have a title that in this format: session 1 - episode 22 and digits are between 0-999 this algorithm won't work and I haven't any sort in my recycler. may please help me for fix this?
I found the solution :)
I must replace the first part with whitespace. then we can get the second part number from string and convert it to int and sort it.
val matcher = pattern.matcher(o1.title?.replace("session 1", ""))
val matcher2 = pattern.matcher(o2.title?.replace("session 1", ""))