Descending order ZoneDateTime in list kotlin - kotlin

I have list of ZoneDateTime. I want to order by descending order. I didn't find the solution. Can some one guide me.
NearestResult(day=2020-05-09T20:09:03+01:00, event=xyz)
NearestResult(day=2020-05-09T09:15:15+01:00, event=abc)
NearestResult(day=2020-05-09T23:15:15+01:00, event=qwe)
NearestResult(day=2020-05-09T14:00:40+01:00, event=aks)
NearestResult.kt
data class NearestResult(
val day: ZonedDateTime,
val event: String
)
I tried some code but it's not working
lis.groupBy { it.day }
It giving me same above order.
Expected Output
NearestResult(day=2020-05-09T23:15:15+01:00, event=qwe)
NearestResult(day=2020-05-09T20:09:03+01:00, event=xyz)
NearestResult(day=2020-05-09T14:00:40+01:00, event=aks)
NearestResult(day=2020-05-09T09:15:15+01:00, event=abc)
Can somone guide me. Many Thanks

val desc = compareByDescending<NearestResult>{
it.day
}
val asc = compareBy<NearestResult>{
it.day
}
val sortedList = list.sortedWith(desc)
println(sortedList)
//or
list.sortedByDescending{ it.day }

list.sortedBy { it.day }.reversed()

Related

How to use Lucene's DistinctValuesCollector?

My objective is to collect distinct values of select fields to provided them as filter options for the frontend. DistinctValuesCollector seems to be the tool for this, however since I haven't found code sample and documentation except for the Javadocs I can't currently correctly construct this collector. Can anyone provide an example?
This is my attempt which doesn't deliver the desired distinct values of the field PROJEKTSTATUS.name.
val groupSelector = TermGroupSelector(PROJEKTSTATUS.name)
val searchGroup = SearchGroup<BytesRef>()
val valueSelector = TermGroupSelector(PROJEKTSTATUS.name)
val groups = mutableListOf(searchGroup)
val distinctValuesCollector = DistinctValuesCollector(groupSelector, groups, valueSelector)
That field is indexed as follows:
document.add(TextField(PROJEKTSTATUS.name, aggregat.projektstatus, YES))
document.add(SortedDocValuesField(PROJEKTSTATUS.name, BytesRef(aggregat.projektstatus)))
Thanks to #andrewJames's hint to a test class I could figure it out:
fun IndexSearcher.collectFilterOptions(query: Query, field: String, topNGroups: Int = 128, mapper: Function<String?, String?> = Function { it }): Set<String?> {
val firstPassGroupingCollector = FirstPassGroupingCollector(TermGroupSelector(field), Sort(), topNGroups)
search(query, firstPassGroupingCollector)
val topGroups = firstPassGroupingCollector.getTopGroups(0)
val groupSelector = firstPassGroupingCollector.groupSelector
val distinctValuesCollector = DistinctValuesCollector(groupSelector, topGroups, groupSelector)
search(query, distinctValuesCollector)
return distinctValuesCollector.groups.map { mapper.apply(it.groupValue.utf8ToString()) }.toSet()
}

About binarySearch() of Kotlin List

I ran the examples in the official Kotlin documentation in the local Android Studio, and found that the results are different from what I expected, but I don’t know what is causing this?
data class Produce(
val name: String,
val price: Double
)
This is the data class I defined
val list2 = listOf(
Produce("AppCode", 52.0),
Produce("IDEA", 182.0),
Produce("VSCode", 2.75),
Produce("Eclipse", 1.75)
)
this is my source list
println(list2.sortedWith(compareBy<Produce> {
it.price
}.thenBy {
it.name
}))
The output on the console is:
[Produce(name=Eclipse, price=1.75), Produce(name=VSCode, price=2.75), Produce(name=AppCode, price=52.0), Produce(name=IDEA, price=182.0)]
I call binarySearch() like this
println("result: ${
list2.binarySearch(
Produce("AppCode", 52.0), compareBy<Produce> {
it.price
}.thenBy {
it.name
}
)
}")
I think the result should be 2, but it is 0
result: 0
I don't know why it turned out like this. Plase help me . thanks a lot
sortedWith() does not modify the list, it returns a new, sorted collection. When calling list2.binarySearch() you still search through original, unsorted list.
You need to either do something like:
list2.sortedWith().binarySearch()
Or create your list with mutableListOf() and then use sort() which sorts in-place.
Broot is right. You need to pass the sorted list to the binarySearch() function. To clarify in code:
val comparator = compareBy<Produce> { it.price }.thenBy { it.name }
val sorted = list2.sortedWith(comparator)
println(sorted.joinToString("\n"))
val foundIndex = sorted.binarySearch(Produce("AppCode", 52.0), comparator)
println("Found at: $foundIndex")
Result:
Produce(name=Eclipse, price=1.75)
Produce(name=VSCode, price=2.75)
Produce(name=AppCode, price=52.0)
Produce(name=IDEA, price=182.0)
Found at: 2

How can I translate this Kotlin code into a better one using high order functions instead of a simple for

I have this function that receives a barcode and looks for a product in a list that has the same barcode. The split( ",") is because there are some products that have more than one barcode written like this: ("barcode1,barcode2")
Could someone help me get a better code using high order functions rather than this for loop?
fun Product.byBarcode(barcode: String?) : Product? {
val productsList = Realm.getDefaultInstance().where(Product::class.java).findAll().toMutableList()
var foundProduct : Product? = null
for (it in productsList){
if ( it.barcode.split(",").contains(barcode)){
foundProduct = it
break
}
}
return foundProduct
}
You can use find
foundProduct = productList.find{ it.barcode.split(',').contains(barcode) }
also I don't think split is really required, in that case
foundProduct = productList.find{ it.barcode.contains(barcode) }

How to convert EnumSet<A> to Set<B>

I have an enum class thats something like this:
enum class SomeType(val id: String) {
TYPE1("A"),
TYPE2("B"),
TYPE3("C"),
TYPE4("D")
}
Now, I need to filter a list of Something which has a String that's stated in SomeType enum. So Basically I have something like this:
class Something(val id: String)
// where the value of id is one of the value of the SomeType's id
I have a list of Something like so:
val somethingList = arrayListOf<Something>(
Something("A"),
Something("B"),
Something("A"),
Something("C"),
Something("D"),
Something("A"),
Something("D")
)
Now I need to filter that somethingList to by the given EnumSet<SomeType>.
So if I have a:
val someTypeSet = EnumSet.of(SomeType.Type3, SomeType.Type2)
the resulting filtered List should be,
val filteredList = arrayListOf<Something>(
Something("B"),
Something("C")
)
My idea is to convert the someTypeSet to a Set<String> and just do something like:
Set<String> setOfSomeTypeIds = convertToSet(someTypeSet)
val filteredList = somethingList.filter { something ->
setOfSomeTypeIds.contains(something.id)
}
Can someone guide me how to convert an EnumSet to a Set of its value?
I also explained the whole process just in case there is a better solution to the problem above.
Anything will be appreciated.
Thanks in advance.
You can use map on any collection to transform it to a new collection with the desired values... i.e. someTypeSet.map { it.id } will already return you a list of string. If you really want to have a Set you can also use something like mapTo. Regarding the filter that might also be simplifiable using the in-keyword, e.g.: somethingList.filter { it.id in setOfSomeTypeIds }.
So summarized:
val setOfSomeTypeIds = someTypeSet.map { it.id }
val filteredList = somethingList.filter { it.id in setOfSomeTypeIds }
You can use the map function after you filter the relevant types.
val filteredSomethings:List<Something> = someTypeSet.filter { something ->
setOfSomeTypeIds.contains(something.id) }.map { Something(it.id) }
It will return a List of Something with the relevant Ids.

Kotlin sort hashmap in descending order

I have val myHashMap = HashMap<String, MutableList<TestItem>>(), hashmap key value is formatted date as a string for example 20-06-2018 how can I sort this hashMap in descending order?
expected result:
22-06-2018 : []
21-06-2018 : []
20-06-2018 : []
I use this code to sort it, but result is in ascending order:
val sortedMap = myHashMap.toSortedMap(compareBy { it })
You can use compareByDescending:
val sortedMap = myHashMap.toSortedMap(compareByDescending { it })
The reason you get the result in ascending order is because (from the values you presented) all dates have month=6 and year=2018. If there are various dates then if you simply do compareByDescending the result will be wrong. Consider these dates:
21-05-2018, 22-4-2018. If you sort descending you will get 1st 22-04-2018!
What you need to do is convert the dates in yyyy-MM-dd and then sort descending:
fun convertDate(d: String): String {
val array = d.split("-")
return array[2] + array[1] + array[0]
}
val sortedMap = myHashMap.toSortedMap(compareByDescending { convertDate(it) })
One more thing: your dates must have 2 digits for month and day and 4 digits for year, dates like 2-5-2018 will give wrong result.
Last edit: no need for - in the concatenation.
This worked for me.
val sortedMap = myHashMap.toSortedMap(reverseOrder())
Reference: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.comparisons/reverse-order.html.