【问题标题】:Kotlin - functional programming recursive implementation of the list filter functionKotlin - 列表过滤函数的函数式编程递归实现
【发布时间】:2020-01-09 19:21:10
【问题描述】:

任务是关于 Kotlin 中的函数式编程,给出了一个密封列表类,我们的任务是递归地实现 map、fold、replaceif、filter 和任何。到目前为止,我已经实现了除过滤器之外的所有功能,但我非常接近,我只是缺少一些东西。

给定列表类:

   sealed class List<T> {

    class Node<T>(val head: T, val tail: List<T>) : List<T>() {
        override fun toString() =
            "${head.toString()} , ${tail.toString()}"
    }

    object Nil : List<Nothing>() {
        override fun toString() = "NIL"
    }

    companion object {
        operator
        fun <T> invoke(vararg values: T): List<T> {
            val empty = Nil as List<T>
            val res = values.foldRight(empty, { v, l -> l.addFirst(v) })
            return res
        }
    }

    fun addFirst(head: T): List<T> = Node(head, this)

    fun removeFirst(): List<T> = when (this) {
        is Nil -> throw IllegalStateException()
        is Node<T> -> this.tail
    }
}

我的 map 和 replaceif 的实现:

fun <T, R> map(list: List<T>, f: (T) -> R): List<R> = when (list) {
    is List.Nil -> List.Nil as List<R>
    is List.Node -> List.Node(f(list.head), map(list.tail, f))
}

fun <T> replaceIf (list : List<T> , f : (T)-> T , p : (T)-> Boolean ):List<T> = when (list) {
    is List.Nil -> List()
    is List.Node -> List.Node(if(p(list.head)) f(list.head) else list.head, replaceIf(list.tail, f, p))
}

最后过滤不完全正确的:

fun <T> filter(list: List<T>, p: (T) -> Boolean): List<T> = when (list) {
    is List.Nil -> List()
    is List.Node -> {
        val it = if(p(list.head)) 'something' else 'something'
        List.Node(it,filter(list.tail, p))
    }
}

我基本上想递归地测试每个元素的 p 是否为真,如果它是,它应该过滤掉那个元素,否则让它通过新的列表。所以我需要改变我的 if/else 'something' 让它工作。

【问题讨论】:

    标签: kotlin filter functional-programming


    【解决方案1】:

    好的,那么,过滤列表的算法是什么?

    1. 如果 Nil 则 Nil
    2. 如果 Node AND predicate(head) 则返回带有过滤尾部的相同列表。
    3. 如果 Node AND !predicate(head) 则仅返回过滤后的尾部

    因此,实现将是:

    fun filter(predicate: (T) -> Boolean): FList<T> = when (this) {
        is Nil -> this
        is Node<T> -> if (predicate(head)) Node(head, tail.filter(predicate)) else tail.filter(predicate)
    }
    

    PS:我将这些函数放在class 范围内,因此我没有将列表传递给函数,而是使用this 指针。这允许链接调用,例如 filter、map 和 foreach:

    FList(0, 1, 2, 3, 4, 5, 6, 7, 8)
        .filter { it % 3 == 0 }
        .map { it * 2 }
        .foreach { println(it) }
    

    【讨论】:

      猜你喜欢
      • 2019-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-26
      • 2016-01-12
      • 2016-06-13
      • 2015-04-30
      • 1970-01-01
      相关资源
      最近更新 更多