Home > Software design >  How to filter multiple elements from the list if matching specific pattern?
How to filter multiple elements from the list if matching specific pattern?

Time:07-08

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}.

CodePudding user response:

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!! }
    }

CodePudding user response:

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)
  • Related