Removing elements from a list which are not in ano

2019-08-24 10:22发布

问题:

I have two mutableLists, listOfA has so many objects including duplicates while listOfB has fewer. So I want to use listOfB to filter similar objects in listOfA so all list will have equal number of objects with equivalent keys at the end. Code below could explain more.

fun main() {
    test()
}

data class ObjA(val key: String, val value: String)
data class ObjB(val key: String, val value: String, val ref: Int)

fun test() {
    val listOfA = mutableListOf(
            ObjA("one", ""),
            ObjA("one", "o"),
            ObjA("one", "on"),
            ObjA("one", "one"),

            ObjA("two", ""),
            ObjA("two", "2"),
            ObjA("two", "two"),

            ObjA("three", "3"),
            ObjA("four", "4"),
            ObjA("five", "five")
    )

    //Use this list's object keys to get object with similar keys in above array.
    val listOfB = mutableListOf(
            ObjB("one", "i", 2),
            ObjB("two", "ii", 5)
    )

    val distinctListOfA = listOfA.distinctBy { it.key } //Remove duplicates in listOfA

    /*    
    val desiredList = doSomething to compare keys in distinctListOfA and listOfB
    for (o in desiredList) {
        println("key: ${o.key}, value: ${o.value}")
    }
    */

    /* I was hoping to get this kind of output with duplicates removed and comparison made.
      key: one, value: one
      key: two, value: two
     */
}

回答1:

If you want to operate directly on that distinctListOfA you may want to use removeAll to remove all the matching entries from it. Just be sure that you initialize the keys of B only once so that it doesn't get evaluated every time the predicate is applied:

val keysOfB = listOfB.map { it.key } // or listOfB.map { it.key }.also { keysOfB ->
distinctListOfA.removeAll {
  it.key !in keysOfB
}
//} // if "also" was used you need it

If you have a MutableMap<String, ObjA> in place after evaluating your unique values (and I think it may make more sense to operate on a Map here), the following might be what you are after:

val map : MutableMap<String, ObjA> = ...
map.keys.retainAll(listOfB.map { it.key })

retainAll just keeps those values that are matching the given collection entries and after applying it the map now contains only the keys one and two.

In case you want to keep your previous lists/maps and rather want a new list/map instead, you may just call something like the following before operating on it:

val newList = distinctListOfA.toList() // creates a new list with the same entries
val newMap = yourPreviousMap.toMutableMap() // create a new map with the same entries


标签: kotlin