0

I have two ArrayLists of different Data classes as given below:

class Record{
    var id: Long = 0
    var RecordId: Int = 0
    var Record: String? = null
    var title: String? = null
    var description: String? = null
    var longDate: Long = 0
}

class Type{
    var id: Long = 0
    var typeId: Int = 0
    var subTypeId: Int = 0
    var typeString: String? = null
    var longDate: Long = 0
}

var recordsList: ArrayList<Record>
var typesList: ArrayList<Type>

Now, I want a merged list of these two which will be sorted based on a common field in both the Objects i.e. longDate. I have tried .associate , sortedBy, sortedWith(compareBy<>) etc. but could not achieve the desired result.

Here, also there is one point to note is that while comparing the two lists it is possible that one on them may be empty.

5
  • 1
    You want a list of Any where you will have to cast items that you retrieve from it? Commented Feb 17, 2021 at 17:03
  • Yes, Exactly I want a list of Any that I can then use in an Adapter Commented Feb 17, 2021 at 17:07
  • 1
    What are you trying do do with the merged list? Feels like an XY problem - maybe there's an alternative approach. Commented Feb 17, 2021 at 17:23
  • @AdamMillerchip, I had a use case in my app where I need to display list which consists of above two lists and in a sorted manner as stated in the question. I would appreciate if you can brief the alternative approach. Though I have got the solution from Tenfour04's answer Commented Feb 17, 2021 at 17:52
  • Everything's far too generic to suggest an alternative right now. Why do they need to be together? Are they in pairs, for example? Commented Feb 17, 2021 at 18:29

2 Answers 2

2

This will produce a List<Any> with all items sorted by longDate:

(recordsList + typesList)
    .sortedBy { 
        when (it) {
            is Record -> it.longDate
            is Type -> it.longDate
            else -> error("")
        }
    }

Or you might consider creating an interface that has val longDate: Long that both of these classes implement. Then you wouldn't need the when expression, and your List would be of the type of the interface.

Sign up to request clarification or add additional context in comments.

4 Comments

It will be more concise to use sortedBy
This worked well, (recordsList + typesList) this was the thing I was looking for. I created an interface to avoid when as you have suggested.
Really, I’d make the interface include everything that is relevant to whatever presents both of these together in a list.
Thanks, @МихаилНафталь
1

Something like this should work, but I personally think that it is quite the code smell. There is no guarantee that Record.longDate is truly the same type as Type.longDate (we know that it is, since we create the model, but the compiler would never know).

val result = (recordsList + typesList).sortedBy {
        when(it){
            is Record -> it.longDate
            is Type -> it.longDate
            else -> error("incompatible list element $it")
        }
    }

And it would work something like this: (I've removed some parameters from the models as they don't really count here)

    
fun main() {
    
    val recordsList = listOf(Record().apply { longDate = 5 }, Record().apply { longDate = 3})
    val typesList =  listOf(Type().apply { longDate = 3 }, Type().apply { longDate = 2 })
    
    val result = (recordsList + typesList).sortedBy {
        when(it){
            is Record -> it.longDate
            is Type -> it.longDate
            else -> error("incompatible list element $it")
        }
    }
    
    result.forEach{
        println(it.toString())
    }
    
}


class Record{
        var longDate: Long = 0
    override fun toString(): String {
        return "Record(longDate=$longDate)"
    }
}

class Type{
    var longDate: Long = 0
    override fun toString(): String {
        return "Type(longDate=$longDate)"
    }
}

This will output:

Type(longDate=2)
Record(longDate=3)
Type(longDate=3)
Record(longDate=5)

Doing it in a more generic way, so that you can create a fun where you state which property to be used from each object type would most likely use reflection, which I'd avoid at all costs.

So I would definitely consider if one object can inherit the other, or create an interface, or anything else.

I'll end with 2 questions: why no constructors? why ArrayList and not list?

Comments

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.