(new to Kotlin) I am writing a function to log differences between two Lists, like so:
fun logDifferences(booksOne: List<Book>?, booksTwo: List<Book>?, logEntryFactory: LogEntryFactory) {
val booksOneByKey: Map<String?, Book> = booksOne?.associateBy({ it.key }, { it }) ?: mapOf()
val booksTwoByKey: Map<String?, Book> = booksTwo?.associateBy({ it.key }, { it }) ?: mapOf()
val allBookKeysSet: Set<String?> = booksOneByKey.keys.union(booksTwoByKey.keys)
allBookKeysSet.forEach {
val bookOne = booksOneByKey[it]
val bookTwo = booksTwoByKey[it]
if (bookOne != bookTwo) {
bookOne?.let { // log the book) }
bookTwo?.let { // log the book)}
}
}
}
The idea is that if a book from booksOne or booksTwo is null, that is still a difference that I would like to capture. But as it is written, I am realizing that if a key can be nullable in my map, how could I even look up the result?
Is there a way of refactoring this to log instances where one list has a null object and not the other, or am I looking at this the wrong way?
CodePudding user response:
Your code works perfectly fine even with null keys. consider this full kotlin program:
data class Book(
val key: String?,
val title: String
)
val list1 = listOf(
Book("1", "Book A"),
Book("2", "Book B"),
Book("3", "Book C"),
)
val list2 = listOf(
Book("2", "Book B"),
Book("4", "Book D"),
Book(null, "Book NullKey"),
)
fun main() {
val booksOneByKey: Map<String?, Book> = list1?.associateBy({ it.key }, { it }) ?: mapOf()
val booksTwoByKey: Map<String?, Book> = list2?.associateBy({ it.key }, { it }) ?: mapOf()
val allBookKeysSet: Set<String?> = booksOneByKey.keys.union(booksTwoByKey.keys)
allBookKeysSet.forEach {
val bookOne = booksOneByKey[it]
val bookTwo = booksTwoByKey[it]
println("key $it :")
if (bookOne != bookTwo) {
bookOne?.let { println("check $it") }
bookTwo?.let { println("check2 $it") }
}
}
}
this will print the following:
key 1 :
check Book(key=1, title=Book A)
key 2 :
key 3 :
check Book(key=3, title=Book C)
key 4 :
check2 Book(key=4, title=Book D)
key null :
check2 Book(key=null, title=Book NullKey)
as you can see it will also take the null book
CodePudding user response:
This is not an answer to the question, as I do not really understand what the issue is. Maybe look and play around with the built-in collection functions:
data class Book(
val key: String,
val title: String
)
val list1 = listOf(
Book("1", "Book A"),
Book("2", "Book B"),
Book("3", "Book C")
)
val list2 = listOf(
Book("2", "Book B"),
Book("4", "Book D")
)
val all = (list1 list2).distinct() // same as: (list1.plus(list2)).distinct()
println(all) // Books 1, 2, 3, 4
val inBoth = list1.intersect(list2)
println(inBoth) // Book 2
val inList1Only = list1.minus(list2)
println(inList1Only) // Books 1, 3
val inList2Only = list2.minus(list1)
println(inList2Only) // Book 4