拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Kotlin中的函式式编程:使用折叠计算串列中的元素

Kotlin中的函式式编程:使用折叠计算串列中的元素

白鹭 - 2022-02-10 2121 0 0

我的任务是使用折叠(函式式编程)撰写一个函式来计算串列中满足谓词的元素数量。我得到了函式签名fun <A> count(list<A>, predicate: (A) -> Boolean): Int折叠不仅要用作迭代,还要生成回传值。所以我试着这样做:

fun <A> count(list: List<A>, predicate: (A) -> Boolean): Int {
        return list.fold(0) {
            acc, a ->
            if (predicate(a)) {
                return acc   1
            }

            return acc
        }
    }

我写了一个 println 来检查它是否有效:

println(count3(listOf (1, -2, 3, 10, -5, 8, 12), { it > 0 && it < 10 }))

但是,我在控制台上得到的结果是 1 而不是 3,我不知道故障出在哪里。那么,有没有人知道我的错误在哪里或者我可以如何实作该功能?

并且要明确一点:Fold 累加一个值,从初始值(在本例中为 0)开始,并将从左到右的操作应用于当前累加器和每个元素,还是我弄错了?

编辑(我希望可以编辑一个问题而不是问一个新问题):

是否可以回传整个串列而不仅仅是一个 int?我刚刚找到了回传整数或布林值的示例。我尝试了什么:我使用了上面相同的函式签名。但我不想回传一个 Int,而是回传一个串列:

fun <A> returnList(list: List<A>, predicate: (A) -> Boolean): List<A> {
        return list.fold(mutableListOf()) {
            acc, a ->
            if (predicate(a)) {
                acc.add(a)
            } else {
                acc
            }
        }
    }

我发现的问题是acc.add(a)回传布林值而不是串列,因此 IDE 将其标记为错误。那么有没有办法回传一个串列?

提前致谢。

uj5u.com热心网友回复:

通过说return你回传整个count函式。你可以return@fold改用。很喜欢

fun <A> count(list: List<A>, predicate: (A) -> Boolean): Int {
    return list.fold(0) {
            acc, a ->
        if (predicate(a)) {
            return@fold acc   1
        }

        return@fold  acc
    }
}

或者,也许更好的是这样做

fun <A> count(list: List<A>, predicate: (A) -> Boolean): Int {
    return list.fold(0) {
            acc, a ->
        if (predicate(a)) {
            acc   1
        } else {
            acc
        }
    }
}

lambda 中的最后一个表达式隐含地也是它的回传值

uj5u.com热心网友回复:

试试这样:

fun <A> count(list: List<A>, predicate: (A) -> Boolean): Int {
    return list.fold(0) { acc, a -> if (predicate(a)) acc 1 else acc }
}

fun main(args: Array<String>) {
    val x = listOf<Int>( 1, -2, 3, 10, -5, 8, 12);
    println(count(x, { it > 0 && it < 10 }))
}

查看此站点使我清楚地了解了必要的更改。

这种形式是否必要,因为 fold 使用尾递回?看看原因是什么很有趣。

uj5u.com热心网友回复:

fun <A> count(list: List<A>, predicate: (A) -> Boolean): Int {
  return list.fold(0) { acc, a -> acc   predicate(a).run { if (this) 1 else 0 } }
}

uj5u.com热心网友回复:

我在 kotlin-forum 中找到了如何使用折叠回传串列(请参阅我的问题编辑)的答案:

而不是写:

fun <A> returnList(list: List<A>, predicate: (A) -> Boolean): List<A> {
        return list.fold(mutableListOf()) {
            acc, a ->
            if (predicate(a)) {
                acc.add(a)
            } else {
                acc
            }
        }
    }

你可以写(下面的解决方案是 al3c在 kotlin 论坛中提供的):

fun <A> returnList(list: List<A>, predicate: (A) -> Boolean): List<A> {
        return list.fold(mutableListOf()) {
            acc, a ->
            if (predicate(a)) {
                acc.add(a)
            } 
            acc
        }
    }

通过这样做,代码回传的不是单个整数、字符或布林值,而是整个串列。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *