How to filter list of objects by the value of the one field in Kotlin? - kotlin

I have got list of objects
listOf(User("John",32), User("Katy",15), User("Sam",43))
How can write a function which returns me the User object if in parameter I pass a name. For example getUser("John") and it suppose to return me User("John",32)

One possibility is also using firstOrNull:
val list = listOf(User("John",32), User("Katy",15), User("Sam",43))
list.firstOrNull { it.name == "John" }

Related

Combining Two List in Kotlin with Index

There is a data class as fruits.
data class Fruits(
val code: String, //Unique
val name: String
)
The base list indexed items with boolean variable is as below.
val indexList: MutableList<Boolean> = MutableList(baseFruitList.size) { false }
Now the Favourite Indexed list is as below
val favList: MutableList<Boolean> = MutableList(favFruitList.size) { true}
I want a combined full list which basically has the fav item indicated as true.
Ex:
baseFruitList = {[FT1,apple],[FT2,grapes],[FT3,banana],[FT4,mango],[FT5,pears]}
favList = {[FT2,grapes],[FT4,mango]}
The final index list should have
finalIndexed = {false,true,false,true,false}
How can we achieve in Kotlin, without iterating through each element.
You can do
val finalIndexed = baseFruitList.map { it in favList }
assuming, like #Tenfour04 is asking, that name is guaranteed to be a specific value (including matching case) for a specific code (since that combination is how a data class matches another, e.g. for checking if it's in another list)
If you can't guarantee that, this is safer:
val finalIndexed = baseFruitList.map { fruit ->
favList.any { fav.code == fruit.code }
}
but here you have to iterate over all the favs (at least until you find a match) looking to see if one has the code.
But really, if code is the unique identifier here, why not just store those in your favList?
favList = listOf("FT2", "FT4") // or a Set would be more efficient, and more correct!
val finalIndexed = baseFruitList.map { it.code in favList }
I don't know what you mean about "without iterating through each element" - if you mean without an explicit indexed for loop, then you can use these simple functions like I have here. But there's always some amount of iteration involved. Sets are always an option to help you minimise that

How to get documents from Firestore where a field which is an array matches a string in Kotlin?

I want to get all documents (products) from the Firestore and then show them in the recyclerVieww. The criterion is that the value that I have should match with the one in the 'deliverable', where the deliverable is an array.
So, get all the documents from the collection 'products' where the value in the field 'deliverable match the one I provide.
I have tried the following but I don't get any result as I expected. Am I doing it wrong?
Can someone help me with it?
fun getProductsDeliverable(deliverable: String) {
mFireStore.collection("products")
.whereEqualTo("deliverable_mun_pan", deliverable).get().addOnCompleteListener {
if (it.isSuccessful) {
for (document in it.result) {
val product = document.toObject(Product::class.java)
product.product_id = document.id
productsList.add(product)
}
} else {
Log.d("TAG", "There are no items")
}
srProductsList.addAll(srProductsList)
successProductsList(srProductsList)
}
What you're describing is known as an array membership query in Firestore, and can be done with
mFireStore.collection("products")
.whereArrayContains("deliverable", "Pune")
So this matches products where the deliverable array contains a value of "Pune". Instead of the hard-coded value, you can also specify your deliverable variable of course.

sort the table by column name Exposed Kotlin

Good afternoon, I want to make a universal sort for all tables. The idea is that the method will receive the name of the column as input and, through reflection, I will receive a link to the field of the same name.
val id = "id"
var a = JobSeekerTable::class
a.memberProperties.forEach { e ->
if (e.name == id) {
transaction {
JobSeeker.all().sortedBy { e.getter }
}
}
}
Unfortunately, this does not work. There was an option, through the fields field that the table has
JobSeekerTable.fields.forEach {v->
transaction {
JobSeeker.all().sortedBy { v }
}
}
but also unsuccessfully :(
If there is any way to refer to the required field through the name. Not using if and stuff like that?
First, you are probably looking for orderBy, not sortedBy. The former is to order SQL query results, the later is to sort a collection.
Second, you want to pass an instance of a column:
val id = "id"
JobSeekerTable.selectAll().orderBy(JobSeekerTable.columns.find {
it.name == id // Here I used the name you provided, although probably it should be named something like columnName
} !! to SortOrder.ASC)
Using "screaming" operator (!!) in Kotlin is a bad practice. So if all of your tables have ID column, for example, you can use "elvis" operator instead.
JobSeekerTable.selectAll().orderBy((JobSeekerTable.columns.find {
it.name == id
} ?: JobSeekerTable.id) to SortOrder.ASC)

How to assign a new list to a nullable field if null or else just add an element to the existing list in Kotlin?

I have an object media that holds descriptions which is a list. I'd love to see some elegant logic in Kotlin to add an element to that descriptions if the field is not null or add a fresh new list (with an initial element) to that field if it is null.
Pseudo:
if (media.descriptions == null) { media.descriptions = listOf("myValue")}
else { media.descriptions.add("myValue") }
I would probably do it the other way around, except you need to alter media itself (see below), i.e. creating your list first and add all the other entries to that list if media.descriptions isn't null:
val myDescriptions = mutableListOf("myValue") // and maybe others
media.descriptions?.forEach(myDescriptions::add)
If you need to manipulate descriptions of media, there is not so much you can do to make it more readable...:
if (media.descriptions == null) {
media.descriptions = mutableListOf("myValue") // just using mutable to make it clear
} else {
media.descriptions += "myValue"
}
or maybe:
if (media.descriptions == null) {
media.descriptions = mutableListOf<String>()
}
media.descriptions?.add("myValue")
You can use the elvis ?: operator to assign the list.
The simplest way I can think of is
media.descriptions = media.descriptions ?: listOf("myValue")
media.descriptions.add("myValue")

Passing a list to SQL each row call Groovy

I am currently rendering a list of sql rows from a database using:
Sql sql = new Sql(dataSource)
def list = []
def index = 0
params.mrnaIds.each { mrnaName ->
sql.eachRow ("select value from patient_mrna where mrna_id=$mrnaId") { row ->
list[index] = row.value
index++
}
}
render list
However I would like to avoid assigning the values to a list before rendering them.
The variable params.mrnaIds is coming from a multi select input, so it could either be a single string or a string array containing ids. Is there a way to iterate through these ids inside the eachRow method?
I would like to be able to execute something like:
render sql.eachRow ("select value from patient_mrna where mrna_id=?", params.mrnaIds) { row ->
list[index] = row.value
index++
}
But I'm not completely sure that there is a way to call eachRow with this functionality. If there is not, is there some other way to render the results without storing them in a list?
I think you can render each row:
sql.eachRow( someQuery, someParams ){ row ->
render row as JSON
}
There is rows() to return a list instead ok working with it (like eachRow() is used for). It also shares all the different arguments. E.g.:
render sql.rows("select value from patient_mrna where mrna_id=?", params).collect{ it.value }