1

I have a list of list that I want to sort based on a date value in inner list. Here's example of my list:

ClassA(id: String, classb : List<ClassB>) and ClassB is ClassB(id: String, date: Date) so I have list of ClassA which also contain list of ClassB and I want to order/sort List based on descending order of dates in inner classB

1
  • do you want a list of ClassB ordered by date with its corresponding ClassA or do you want a list of ClassA where only the ClassB are ordered by date for each ClassA... or in other words: what should happen if there are two ClassB-dates of any ClassA-object that are both before and after other ClassA-object-contained ClassB-dates? Commented Sep 24, 2019 at 10:10

2 Answers 2

1

Assuming the following:

val int = AtomicInteger(0)
data class A(val bs: List<B>, val id: Int = int.incrementAndGet())
data class B(val date: LocalDate, val id: Int = int.incrementAndGet())

and a list (listOfA) as follows:

A(bs=[B(date=2019-09-24, id=1), B(date=2019-09-25, id=2), B(date=2019-09-23, id=3)], id=4)
A(bs=[B(date=2019-09-21, id=5), B(date=2019-09-22, id=6), B(date=2019-09-23, id=7)], id=8)
A(bs=[B(date=2019-09-19, id=9), B(date=2019-09-23, id=10), B(date=2019-09-29, id=11)], id=12)
  1. only ordering the class B elements (actually I create a new list with completely new A-objects... if you do not want that, this can still serve as a starting point):

    val listOfAWithOrderedB = listOfA.map {
      it.copy(bs = it.bs.sortedByDescending(B::date))
    }
    

    which leads to:

    A(bs=[B(date=2019-09-25, id=2), B(date=2019-09-24, id=1), B(date=2019-09-23, id=3)], id=4)
    A(bs=[B(date=2019-09-23, id=7), B(date=2019-09-22, id=6), B(date=2019-09-21, id=5)], id=8)
    A(bs=[B(date=2019-09-29, id=11), B(date=2019-09-23, id=10), B(date=2019-09-19, id=9)], id=12)
    
  2. ordering by all B-dates and keeping a reference to the actual A:

    val bSortedByDateAndTheirA = listOfA.flatMap { anA ->
      anA.bs.map {
        it to anA
      }
    }
        .sortedByDescending { (b) -> b.date }
    

    which leads to a List<Pair<B, A>> (again... a possible starting point) as follows:

    (B(date=2019-09-29, id=11), A(bs=[B(date=2019-09-19, id=9), B(date=2019-09-23, id=10), B(date=2019-09-29, id=11)], id=12))
    (B(date=2019-09-25, id=2), A(bs=[B(date=2019-09-24, id=1), B(date=2019-09-25, id=2), B(date=2019-09-23, id=3)], id=4))
    (B(date=2019-09-24, id=1), A(bs=[B(date=2019-09-24, id=1), B(date=2019-09-25, id=2), B(date=2019-09-23, id=3)], id=4))
    (B(date=2019-09-23, id=3), A(bs=[B(date=2019-09-24, id=1), B(date=2019-09-25, id=2), B(date=2019-09-23, id=3)], id=4))
    (B(date=2019-09-23, id=7), A(bs=[B(date=2019-09-21, id=5), B(date=2019-09-22, id=6), B(date=2019-09-23, id=7)], id=8))
    (B(date=2019-09-23, id=10), A(bs=[B(date=2019-09-19, id=9), B(date=2019-09-23, id=10), B(date=2019-09-29, id=11)], id=12))
    (B(date=2019-09-22, id=6), A(bs=[B(date=2019-09-21, id=5), B(date=2019-09-22, id=6), B(date=2019-09-23, id=7)], id=8))
    (B(date=2019-09-21, id=5), A(bs=[B(date=2019-09-21, id=5), B(date=2019-09-22, id=6), B(date=2019-09-23, id=7)], id=8))
    (B(date=2019-09-19, id=9), A(bs=[B(date=2019-09-19, id=9), B(date=2019-09-23, id=10), B(date=2019-09-29, id=11)], id=12))
    
Sign up to request clarification or add additional context in comments.

5 Comments

if you want to have a mixture of both... sorting list A corresponding to its B-dates, then you need to tell what should happen if there are several dates within one A that could be before/after any other A'.
I will need mixture of both (sorting list A corresponding to its B-dates). My dates are actually DateTime and there's a guarantee that two dates in classB in two classA won't be the same, at least there will be a time difference. Thanks for the above, will try it
so do you have cases, such as in my example, where A(id=4) contains B-dates that are actually both, before and after some B-dates of A(id=12)... how would you want to order that?
sorry for late reply. I would show the outer entries with higher size first. This that possible? Also I see your solution involves Pairs<A, B> output, how can I get the output in original format i.e instead of List<Pair<A, B>> but List<List<B>>
hmmm... maybe I wasn't clear enough or I don't understand what you really want... in my second approach I basically have each corresponding A in the pair... however each A still has its complete list of all possible Bs... so if you say List<List<B>> what do you really expect? if you only need the B-dates to be sorted, you can also just do listOfAs.flatMap { bs }.sortedByDescending { it.date }
0

you can use Comparator to use this... here the code sample that you can use

Comparator object

companion object : Comparator<MyDate> {

override fun compare(a: MyDate, b: MyDate): Int = when {
    a.year != b.year -> a.year - b.year
    a.month != b.month -> a.month - b.month
    else -> a.day - b.day
}}

date model class

data class MyDate (val year: Int, val month: Int, val day: Int) {}

and this is how you can perform sorting

fun main(args: Array<String>) {
val myDates = listOfdays
myDates.sortedWith(CompareObjects).forEach { 

    add sorted list
}}

1 Comment

instead of using your own comparator, you may also be interested in compareBy... that way you could also write something like listOfB.sortedWith(compareBy { it.date })...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.