3

I want to remove all duplicate objects of one type from a list.

For Eg.

 val models: MutableList<Model> = MutableList<DrawableModel>
 models.add(Student)
 models.add(Student)
 models.add(Teacher)
 models.add(Teacher)
 models.add(Teacher)

Expected Output:

Student
Student
Teacher

I want only one instance of a teacher on the list.

I tried with

models.distinctBy{ it is Teacher}

But it is applying distinct to the entire list not to a particular object and returns.

Student
Teacher
4
  • Why there are 2 Srudents in the expected output? An item at index 0 is the same as the item on index 1. Commented Sep 8, 2020 at 14:14
  • @iknow yes my requirement is I want only one instance of Teacher and rest will remain same. Commented Sep 8, 2020 at 14:17
  • So You only want to have one Teacher in the list and all Students stay? Commented Sep 8, 2020 at 14:20
  • @iknow yes only but models.distinctBy{ it is Teacher} is not working. Commented Sep 8, 2020 at 14:24

3 Answers 3

2

You can try something like this:

object Kotlin
{
    @JvmStatic
    fun main(args: Array<String>)
    {
        val teacher = Teacher(0, "T1");
        val student = Student(1, "S1")

        val models = mutableListOf(teacher, teacher, student, student, student)
        
        // creating new list which is connection of two lists. First -> only Students. Second -> Distinct Teacher
        val newModels = models.filterIsInstance<Teacher>().distinct() + models.filterIsInstance<Student>()

        println(models) // [Teacher(ID=0, name=T1), Teacher(ID=0, name=T1), Student(ID=1, name=S1), Student(ID=1, name=S1)]
        println(newModels) // [Teacher(ID=0, name=T1), Student(ID=1, name=S1), Student(ID=1, name=S1)]
}

// classes like in the question.
open class Model(val id: Int)

data class Teacher(val ID: Int, val name: String) : Model(ID)

data class Student(val ID: Int, val name: String) : Model(ID)

So basically it is the main part:

val newModels = models.filterIsInstance<Teacher>().distinct() + models.filterIsInstance<Student>()
Sign up to request clarification or add additional context in comments.

Comments

0

You can set a Boolean so it skips the first one it finds.

var first = true
models.removeAll { if (it is Teacher) (!first).also { first = false } else false }

If you want a new list, use filterNot instead of removeAll.

distinctBy doesn't work because it's converting the objects to distinct keys. Since you're key type is Boolean, there can only be two items in the list.

Comments

0

Try this:

var list =  arrayListOf<Any>()
    list.add(Person("JAVA",20))
    list.add(Person("JAVA",20))
    list.add(Student("SQL",24))
    list.add(Student("SQL",24))
    list.add(Student("SQL",24))

    var filterList = arrayListOf<Any>()
    var studentCount = 0

    // filtering student object only 
    list.forEach {
        if (it is Student && studentCount == 0) {
            studentCount++
            filterList.add(it)
        } else if (it is Person) filterList.add(it)
    }
    filterList.stream().forEach { println(it) }// output : [JAVA,20],[JAVA,20],[SQL,24]

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.