Обработка списков двух разных типов с помощью одного и того же кода с использованием функционального программирования в kotlin - PullRequest
0 голосов
/ 02 октября 2018

У меня есть два списка с разными типами list1 и list2.У меня есть метод, который делает ту же операцию над списками.

Я использую лямбда-выражения, где я не могу получить доступ к свойству как (it.prop1), если я использую список типа Any.

Есть ли какое-либо решение, чтобы избежать этой проблемы с лямбдами?

val list1: List<Student> = ..
val list2: List<Teacher> = ..

list1.filter {
    school.contains(it.prop1) }
.forEach {
    total +=  it.prop2.toLong()
}

list2.filter {
    school.contains(it.prop1) }
.forEach {
    total +=  it.prop2.toLong()
}

Спасибо.

Ответы [ 3 ]

0 голосов
/ 02 октября 2018

Вы можете использовать Тип проверки и приведения

class Student(val prop1:Int, val prop2:Int)
class Teacher(val prop1:Int, val prop2:Int)
val list : List<Any> = listOf(Student(1,1),Student(2,2),Student(3,3),Teacher(1,1),Teacher(2,2),Teacher(3,3))
var total : Long = 0
val school : Array<Int> = arrayOf(1,2)
list.filter{
    if(it is Student)
    {
        school.contains((it as Student).prop1)
    }
    else if(it is Teacher)
    {
        school.contains((it as Teacher).prop1)
    }
    else
    {
        false
    }
}.forEach{
    if(it is Student)
    {
        total += (it as Student).prop2.toLong()
    }
    else if(it is Teacher)
    {
        total += (it as Teacher).prop2.toLong()
    }

}
println(total)  //print 6 in this example

Это ужасно сложно.Лучше заставить Student и Teacher либо наследовать общий суперкласс, либо реализовать общий интерфейс

0 голосов
/ 02 октября 2018

Попробуйте это:

object Test {

    private fun isContains(school: Set<Int>, any: Any) = when (any) {
        is Student -> school.contains(any.prop1)
        is Teacher -> school.contains(any.prop1)
        else -> false
    }

    private fun value(any: Any) = when (any) {
        is Student -> any.prop2
        is Teacher -> any.prop2
        else -> throw NoWhenBranchMatchedException("any should be Student or Teacher")
    }

    @JvmStatic
    fun main(args: Array<String>) {
        val school = setOf(1, 2)
        val list = listOf(Student(1, 1), Student(2, 2), Student(3, 3), Teacher(1, 1), Teacher(2, 2), Teacher(3, 3))

        val total = list.filter {
            isContains(school, it)
        }.map {
            value(it)
        }.sum()

        println("Total: $total")
    }

    private class Student(val prop1: Int, val prop2: Int)

    private class Teacher(val prop1: Int, val prop2: Int)
}
0 голосов
/ 02 октября 2018

Насколько я знаю, ты не можешь.Вы можете воспользоваться общим интерфейсом.

Например:

interface Human{
    val age: Int
}

class Student(override val age: Int): Human

class Teacher(override val age: Int, val salary: Double):Human

fun x(){
    val list1: List<Student> = ...
    val list2: List<Teacher> = ...
    val school: List<Human> = ...

    val result = school
        .filter { it is Student }
        .sumBy { it.age}

    val result2 = school
        .filter { it is Teacher }
        .sumBy { it.age }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...