chrisChris
chrisChris

Reputation: 99

How to filter multiple elements from the list if matching specific pattern?

I have list of Work model elements.

Work has paremeters like:

id,
title,
number,
version number

I would like to have only Work elements where version number is not null and take the highest version number of existing elements. For example my list has Work elements like (in order title, number, version)

Running (120:1)
Running (120:2)
Running (120:3)
Climbing (55:1)
Climbing (55:2)
Climbing (55:3)
Climbing (55:4)

My result in the list after filters should be

Running (120:3)
Climbing (55:4)

My code so far:

    private fun List<Work>.filterByVersion(): List<Work> {

                work.version_number != null
        }.filter { work -> ("${work.title} ${work.number}:${work.version_number}").contains("no idea of regex here")
     }
    }

I was thinking something like inner search with {work.title} ${work.number}: then find in here the max value of {work.version_number}.

Upvotes: 0

Views: 602

Answers (2)

lukas.j
lukas.j

Reputation: 7163

data class Work(
  val id: Int,
  val title: String,
  val number: Int,
  val versionNumber: Int
)

val works = listOf(
  Work(1, "Running", 120, 1),
  Work(2, "Running", 120, 2),
  Work(3, "Running", 120, 3),
  Work(4, "Climbing", 55, 1),
  Work(5, "Climbing", 55, 2),
  Work(6, "Climbing", 55, 3),
  Work(7, "Climbing", 55, 4)
)

fun List<Work>.filterByVersion() = this
  .groupBy { it.number }
  .map { (_, list) -> list.maxBy { it.versionNumber } }

val result = works.filterByVersion()

result.forEach(::println)

Upvotes: 0

Sergio
Sergio

Reputation: 30635

The following code works for me:

private fun List<Work>.filterByVersion(): List<Work> =
    groupBy { it.number }.map {
        it.value
            .filter { work -> work.version_number != null }
            .maxByOrNull { work -> work.version_number!! }
    }.filterNotNull()

First we convert current list into a Map<Int, List<Work>>, where the key is Work.number then we map resulting Map into a List<Work> by filtering non null values of version_number and finding the max value of it.


Another variation:

private fun List<Work>.filterByVersion(): List<Work> =
    groupBy { it.number }.values.mapNotNull { works ->
        works
            .filter { work -> work.version_number != null }
            .maxByOrNull { work -> work.version_number!! }
    }

Upvotes: 1

Related Questions