Tendai
Tendai

Reputation: 81

How to filter elements in one list by a property value not present in elements in another list?

I have the following code snippet

val cachedNews = listOf(News(9, "https://009"), News(8, "https://234"), News(7, "https://345"))
val freshNews = listOf(News(1, "https://123"), News(2, "https://234"), News(3, "https://345"))

val result = freshNews.filter {fresh -> filter(cachedNews, fresh)}

private fun filter(cached: List<News>, fresh: News): Boolean {
cached.forEach { cachedItem ->
    if (cachedItem.url == fresh.url) return true
}
return false }

When the code runs if cachedItem.url == fresh.url the list is filtered and the result is a list where the urls of the two lists are identical. However when i reverse equality like so cachedItem.url != fresh.url the list is not filtered at all. The sequence of execution changes.

When using the == sign, the first item of freshNews is compared with the first Item of cachedNews after that the secondItem of freshNews is compared with secondItem of cachedNews and so on.

When I use the != sign the all items of freshNews are compared against only the firstItem of cachedNews ??

Am I missing something or is my code just wrong?

Upvotes: 1

Views: 1190

Answers (1)

Adam Millerchip
Adam Millerchip

Reputation: 23091

I'm not sure what the specific problem is because your approach is quite confusing. Your custom filter function is actually more like a contains function.

What might be useful is to:

  1. Extract the cached URLs to a set
  2. Filter the new results by URLs that are not in the set.
fun main() {
    val cachedNews = listOf(News(9, "https://009"), News(8, "https://234"), News(7, "https://345"))
    val freshNews = listOf(News(1, "https://123"), News(2, "https://234"), News(3, "https://345"))

    val cachedUrls = cachedNews.map { it.url }.toSet()
    val result = freshNews.filterNot { cachedUrls.contains(it.url) }
    println(result)
}

Result:

[News(id=1, url=https://123)]

Upvotes: 4

Related Questions