Kotlin-Null Safety - kotlin

Well...the question is --> "Write a program to check for the null value of the variables x and y using 'Elvis' operator and '!!' operator. Need to complete the function nullable. It should return the length of the string if it is not null, otherwise -1"
fun nullable(nullableString: String?): Int {
}
fun main(args: Array<String>) {
val str = readLine()!!
var result = -100
if(str=="null") {
result = nullable(null)
}else
result = nullable(str)
println(result)
}

fun nullable(nullableString: String?): Int {
return nullableString?.length ?: -1
}

Basically just return the input length using the Elvis operator or -1 if the input is null.
fun nullable(nullableString: String?): Int = nullableString?.length ?: -1

fun nullable(nullableString: String?, default: Int): Int {
return nullableString?.toIntOrNull() ?: default
}
fun main(args: Array<String>) {
val str = readlnOrNull()
val result = -1
println(nullable(str, result))
}
Here 'str' variable accepts value while the default is -1 it returns default -1 or int value, this is with Elvis operator but you want length instead of value so here is the solution
fun nullable(nullableString: String?, default: Int): Int {
return if (nullableString?.length == 0) {
default
} else {
nullableString?.length!! // !! is called the 'not-null assertion operator'
}
}
fun main(args: Array<String>) {
val str = readlnOrNull()
val result = -1
println(nullable(str, result))
}

Related

Kotlin. Find element by param in nested lists

I have some data clases
data class Data(val docNumber: Int?,
val docType: Int?,
val fiscprops: List<FiscProp>,
val name: String?
) {
fun getFiscProp(tag: Int) = fiscprops.firstOrNull { it.tag == tag }
}
data class FiscProp(val caption: String?,
val printable: String?,
val tag: Int?,
val value: Any?,
val fiscprops: List<FiscProp>?)
I need to find FiscProp by tag in nested lists. If I use getFiscProp I can find FiscProp only if it is on first level of hierarchy.
How can I find element on the all levels? I don't know how many levels will be.
val FiscProp.allProps: Sequence<FiscProp>
get() = sequence {
yield(this#allProps)
fiscprops?.forEach {
yieldAll(it.allProps)
}
}
class Data(...) {
fun getFiscProp(tag: Int) = fiscprops.asSequence()
.flatMap { it.allProps}
.firstOrNull { it.tag == tag }
}
You can use a basic recursive search for this:
fun List<FiscProp>.getFiscProp(tag: Int): FiscProp? {
for (fiscProp in this) {
if (fiscProp.tag == tag)
return fiscProp
val found = fiscProp.fiscprops?.getFiscProp(tag)
if (found != null)
return found
}
return null
}
I think this functional version might work too, but I didn't test it:
fun List<FiscProp>.getFiscProp(tag: Int): FiscProp? = firstNotNullOfOrNull {
if (it.tag == tag) it else it.fiscprops?.getFiscProp(tag)
}
Here's a tail-recursive version.
data class Data(...) {
fun findByTag(tag: Int) = findByTag(fiscprops, tag)
private tailrec fun findByTag(fiscprops: List<FiscProp>, tag: Int): FiscProp? =
if (fiscprops.isEmpty()) null
else {
val fiscprop = fiscprops.first()
if (fiscprop.tag == tag) fiscprop
else findByTag(fiscprops.drop(1) + fiscprop.fiscprops.orEmpty(), tag)
}
}

how to create and call extension function in Kotlin

fun main(args: Array<String>) {
val comingvalue = "\"6340040278031835\"".replace("[^0-9]".toRegex(), "");
print(getAuthDigits(comingvalue))
}
fun getAuthDigits( number :String?): String? {
return if (number?.length ?: 0 < 14) {
null
} else {
number?.substring(10, 14)
}
}
This is the function I am calling in the main method. Can anyone please suggest how to create an extension function and how to call it main method with a comingvalue input parameter?
fun String.getAuthDigits(): String? {
return if (this.length ?: 0 < 14) {
null
} else {
this.substring(10, 14)
}
}
and call this like below
fun main(args: Array<String>) {
val comingvalue = "\"6340040278031835\"".replace("[^0-9]".toRegex(), "");
print(comingvalue.getAuthDigits())
}
If this is the only place you call that function, you may as well write it inline.
You can use takeIf() to return null if the condition is not satisfied:
fun main() {
val authDigits: String? = """"6340040278031835""""
.takeIf { it.length >= 14 }?.substring(10, 14)
println(authDigits)
}
Output:
8031

Using Kotlin to build classes with Generic data types

I'm in the process of building my Kotlin and general programming knowledge and trying to follow good practices while doing so. I am working on a project with some important matrix manipulation so I decided I would build my own Matrix class and define the logic myself.
I could have just built it two accept Doubles. But I wanted to build it to support any numeric type and even allow other classes that I define like fractions or complex numbers.
I also wanted to make the values of the matrix private so that you only access values through specific methods. mostly because that seems best practice development for future projects dealing with secure data.
The Issue: Now set up as an interface. still room for improvement. One thing I was struggling to do was to find a way to have a parameter for the interface, that stores the multiplicative identity (1) and one for the additive identity (0) that is implemented for each class. For some reason this didn't seem to work.
interface MyNumber<T> {
operator fun plus(other: T): MyNumber<T>
operator fun unaryMinus(): MyNumber<T>
operator fun minus(other: T): MyNumber<T>
operator fun times(other: T): MyNumber<T>
operator fun div(other: T): MyNumber<T>
operator fun compareTo(other: T): Int
}
class MyInt(val value: Int): MyNumber<MyInt> {
override fun plus(other: MyInt) = MyInt(value + other.value)
override fun unaryMinus() = MyInt(-value)
override fun minus(other: MyInt) = MyInt(value - other.value)
override fun times(other: MyInt) = MyInt(value * other.value)
override fun div(other: MyInt) = MyInt(value / other.value)
override fun toString() = value.toString()
override fun equals(other: Any?): Boolean {
return when{
other is MyInt -> value == other.value
other is Int -> value == other
else -> false
}
}
override fun compareTo(other: MyInt) = value.compareTo(other.value)
}
class MyLong(val value: Long): MyNumber<MyLong> {
override fun plus(other: MyLong) = MyLong(value + other.value)
override fun unaryMinus() = MyLong(-value)
override fun minus(other: MyLong) = MyLong(value - other.value)
override fun times(other: MyLong) = MyLong(value * other.value)
override fun div(other: MyLong) = MyLong(value / other.value)
override fun toString() = value.toString()
override fun equals(other: Any?): Boolean {
return when{
other is MyLong -> value == other.value
other is Long -> value == other
else -> false
}
}
override fun compareTo(other: MyLong) = value.compareTo(other.value)
}
class MyDouble(val value: Double): MyNumber<MyDouble> {
override fun plus(other: MyDouble) = MyDouble(value + other.value)
override fun unaryMinus() = MyDouble(-value)
override fun minus(other: MyDouble) = MyDouble(value - other.value)
override fun times(other: MyDouble) = MyDouble(value * other.value)
override fun div(other: MyDouble) = MyDouble(value / other.value)
override fun toString() = value.toString()
override fun equals(other: Any?): Boolean {
return when{
other is MyDouble -> value == other.value
other is Double -> value == other
else -> false
}
}
override fun compareTo(other: MyDouble) = value.compareTo(other.value)
}
class Fraction private constructor(val num: Long, val div: Long): MyNumber<Fraction> {
data class Builder(var numerator: Long = 0L, var divisor: Long = 1L) {
fun build(numerator: Long, divisor: Long): Fraction {
if (divisor == 0L) {throw ArithmeticException("Cannot divide by Zero")}
this.numerator = numerator
this.divisor = divisor
val gcd = gcd(numerator, divisor)
val sign = sign(divisor.toDouble()).toLong()
return Fraction(sign * numerator / gcd, sign * divisor / gcd)
}
}
val value = num.toDouble()/div
override fun plus(other: Fraction) =
Builder().build(num * other.div + div * other.num, div * other.div)
override fun unaryMinus() = Fraction(-num, div)
override fun minus(other: Fraction) = this + -other
override fun times(other: Fraction) =
Builder().build(num * other.num, div * other.div)
fun invert() = Builder().build(div, num)
override fun div(other: Fraction) = this * other.invert()
override fun toString() = "$num / $div"
override fun equals(other: Any?): Boolean {
return when{
other is Fraction -> num * other.div == div * other.num
other is Double -> value == other
else -> false
}
}
override fun compareTo(other: Fraction) = value.compareTo(other.value)
}
class Complex(val real: Double, val image: Double): MyNumber<Complex> {
val abs = sqrt(real * real + image * image)
override fun plus(other: Complex) = Complex(real + other.real, image + other.image)
override fun unaryMinus() = Complex(-real, -image)
override fun minus(other: Complex) = this + -other
operator fun times(scalar: Double) =
Complex(real * scalar, image * scalar)
operator fun div(scalar: Double) = this * (1/scalar)
override fun times(other: Complex) =
Complex(real * other.real - image * other.image, real * other.image + image * other.real)
fun conj() = Complex(real, -image)
fun invert() = this.conj() / (this * this.conj()).abs
override fun div(other: Complex) = this * other.invert()
override fun toString() = "$real + ${image} i"
override fun equals(other: Any?): Boolean {
return when{
other is Complex -> real == other.real && image == other.image
other is Double -> real == other && image == 0.0
else -> false
}
}
override fun compareTo(other: Complex) = real.compareTo(other.real)
}
#Suppress("UNCHECKED_CAST")
class Matrix<T: MyNumber<T>>(val width: Int, val height: Int, private val values: List<List<MyNumber<T>>>) {
data class Builder(var width: Int = 0, var height: Int = 0) {
fun parameters(width: Int, height: Int) {
this.width = width
this.height = height
}
fun <T: MyNumber<T>> build(data: List<T>): Matrix<T> {
val values = List(height) { j -> List(width) {
i -> data[(j * width + i) % data.size]
}}
return Matrix(width, height, values)
}
}
fun getRowOrNull(j: Int): List<MyNumber<T>>? {
if (j in 0 until height) {
return values[j]
}
return null
}
fun getIndexed(i: Int, j: Int): MyNumber<T> {
return values[j][i]
}
fun getColOrNull(i: Int): List<MyNumber<T>>? {
if (i in 0 until width) {
return List(height) { j -> values[j][i]}
}
return null
}
operator fun plus(other: Matrix<T>): Matrix<T>? {
if (width != other.width || height != other.height ) {
return null
}
val newData = List(height) { j -> List(width) {
i -> getIndexed(i, j).plus(other.getIndexed(i, j) as T)
}}
return Matrix(width, height, newData)
}
operator fun times(other: Matrix<T>): Matrix<T>? {
if (width != other.height) {
return null
}
val newData = List(height) { j -> List(other.width) {
i -> values[j].mapIndexed { k, v -> (v * other.values[k][i] as T) }
.reduce{acc, it -> acc + it as T }
}}
return Matrix(other.width, height, newData)
}
fun transpose(): Matrix<T> {
val newData = List(width) { i -> List(height) {
j -> values[j][i]
}}
return Matrix(height, width, newData)
}
fun getMinor(i: Int, j: Int): Matrix<T>? {
if (i in 0 until width && j in 0 until height) {
val newData = List(height - 1) { y ->
List(width - 1) { x ->
when {
x < i && y < j -> values[y][x]
x < i -> values[y + 1][x]
y < j -> values[y][x + 1]
else -> values[y + 1][x + 1]
}
}
}
return Matrix(width - 1, height - 1, newData)
}
return null
}/*
fun determinate(): T {
}
fun coFactor(i: Int, j: Int): T {
sign = if ((i + j) % 2 == 0) 1
}*/
override fun toString(): String {
var string = ""
for (j in 0 until height) {
string += getRowOrNull(j)?.toString() + "\n"
}
return string
}
}

Invoking Action by reference in Kotlin

I've a Map of (key, value) where the value is a predefined function.
I want to iterate the input param in the Mp and check where the key is matching with the input parameter, then invoke the equivalent function, something like this
My code required to be something like below:
fun fn1: Unit { // using Unit is optional
println("Hi there!")
}
fun fn2 {
println("Hi again!")
}
fun MainFun(x: int){
val map: HashMap<Int, String> = hashMapOf(1 to fn1, 2 to fn2)
for ((key, value) in map) {
// if key = x then run/invoke the function mapped with x, for example if x = 1 then invoke fn1
}
}
Notes: I read something like below, but could not know how to us them:
inline fun <K, V> Map<out K, V>.filter(
predicate: (Entry<K, V>) -> Boolean
): Map<K, V> (source)
val russianNames = arrayOf("Maksim", "Artem", "Sophia", "Maria", "Maksim")
val selectedName = russianNames
.filter { it.startsWith("m", ignoreCase = true) }
.sortedBy { it.length }
.firstOrNull()
Hi I hope this would help you.
fun fn1() {
println("Hi there!")
}
fun fn2() {
println("Hi again!")
}
fun main(args: IntArray){
val map = hashMapOf(
1 to ::fn1,
2 to ::fn2)
map.filterKeys { it == args[0] } // filters the map by comparing the first int arg passed and the key
.map { it.value.invoke() } // invoke the function that passed the filter.
}
If the keyis RegEx then map.filterKeys { Regex(it).matches(x) } can be used, below full example of it Try Kotlin:
data class Person(val name: String,
val age: Int? = null)
val persons = listOf(Person("Alice"),
Person("Bob", age = 23))
fun old() {
val oldest = persons.maxBy { it.age ?: 0 }
println("The oldest is: $oldest")
}
fun young() {
val youngest = persons.minBy { it.age ?: 0 }
println("The youngest is: $youngest")
}
fun selection(x: String) {
val map = mapOf(
"old|big" to ::old,
"new|young" to ::young)
map.filterKeys { Regex(it).matches(x) }
.map { it.value.invoke() }
}
fun main(args: Array<String>) {
selection("new")
}
fun fn1() {
println("Hi there!")
}
fun fn2() {
println("Hi again!")
}
fun main(args: Array<Int>){
val map = hashMapOf(1 to ::fn1, 2 to ::fn2)
map.forEach { key, function -> function.invoke() }
}
This will do the work but your code does not even have the correct syntax. You should learn the basic first.

kotlin check type incompatible types

I've tried code as below
val a: Int? = 1024
println(a is Int) // true
println(a is Int?) // true
println(a is String) // **error: incompatible types: Long and Int? why the value cannot be checked with any type?**
but this works well:
fun checkType(x: Any?) {
when(x) {
is Int -> ...
is String -> ... // **It works well here**
else -> ...
}
}
It works this way:
fun main(args: Array<String>) {
val a = 123 as Any? //or val a: Any = 123
println(a is Int) // true
println(a is Int?) // true
println(a is String) //false
checkType(a) //Int
}
fun checkType(x: Any?) {
when(x) {
is Int -> println("Int")
is String -> println("String")
else -> println("other")
}
}
It's because val a: Int? is definetely not one of String type, compilator knows it and doesn't allow you to run a is String.
You should use more abstract type to define your variable.
You don't need to create a separate function to check its type. You can simply cast to Any? type:
println(a as Any? is String)