gpt4 book ai didi

scala - 是否可以将多个 map 和 reduce 函数组合到 Scala 中的单个 channel 中?

转载 作者:行者123 更新时间:2023-12-03 16:49:03 25 4
gpt4 key购买 nike

我有多个 map 函数在相同的数据上运行,我想让它们一次运行。我正在寻找一种通用的方法来做到这一点。

val fruits: Seq[String] = Seq("apple", "banana", "cherry")

def mapF(s: String): Char = s.head
def reduceF(c1: Char, c2: Char): Char = if(c1 > c2) c1 else c2

def mapG(s: String): Int = s.length
def reduceG(i1: Int, i2: Int): Int = i1 + i2

val largestStartingChar = fruits.map(mapF).reduce(reduceF)
val totalStringLength = fruits.map(mapG).reduce(reduceG)

我想减少通过 fruits 的次数.我可以使这两个 map 通用,并像这样减少:

def productMapFunction[A, B, C](f: A=>B, g: A=>C): A => (B, C) = {
x => (f(x), g(x))
}

def productReduceFunction[T, U](f: (T, T)=>T, g: (U, U) => U):
((T,U), (T,U)) => (T, U) = {
(tu1, tu2) => (f(tu1._1, tu2._1), g(tu1._2, tu2._2))
}

val xMapFG = productMapFunction(mapF, mapG)
val xReduceFG = productReduceFunction(reduceF, reduceG)

val (largestStartingChar2, totalStringLength2) =
fruits.map(xMapFG).reduce(xReduceFG))

我想用任意数量的 map 和 reduce 函数更一般地执行此操作,但我不确定如何进行,或者是否可能。

最佳答案

有趣的问题!

我不知道标准库甚至 scalaz/cats 中有任何这样的实现。
这并不奇怪,因为如果您的列表不是很大,您可以按顺序执行 map-reduces,我什至不确定构建大量中间对象的开销是否会小于多次遍历列表的开销。

如果列表可能不适合内存,您应该使用流库之一( fs2/zio-streams/akka-streams )

尽管如果您的输入是 Iterator而不是 List ,这样的功能会很有用。

有一篇关于这个问题的有趣文章:
https://softwaremill.com/beautiful-folds-in-scala/

域名:
Map-reduce 工作流可以形式化如下:

trait Fold[I, O] {
type M
def m: Monoid[M]

def tally: I => M
def summarize: M => O
}

在你的情况下 I = List[A] , tally = list => list.map(mapF) , summarize = list => list.reduce(reduceF) .

list 上运行 map-reduce使用 fold 的实例你需要跑
fold.summarize(fold.tally(list))
您可以定义 combine对它们的操作:
def combine[I, O1, O2](f1: Fold[I, O1], f2: Fold[I, O2]): Fold[I, (O1, O2)]

使用 combine几次会给你你想要的:
combine(combine(f1, f2), f3): Fold[I, ((O1, O2), O3)]

关于scala - 是否可以将多个 map 和 reduce 函数组合到 Scala 中的单个 channel 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61546686/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com