考虑示例
library(arm)
by(df, df$category,
function(x) lapply(subset(x, select = -c(category, outcome)),
binnedplot, x$outcome))
合并归约函数采用两个列表和两个函数,其中一个函数充当合并,另一个函数将其归纳为更通用的Integer形式。
通过将两个列表的头部相乘然后使用add来减少合并 使用max合并,然后获取所生成列表的最小值
val a= List(1,2,3)
val b= List(4,5,6)
这可以使用内置函数来实现,但是还有一种更好的方法,而不必以递归方式使用这些函数。
答案 0 :(得分:1)
这是您的mergeReduce()
(据我了解)。
def mergeReduce(a :List[Int], b :List[Int]
,f :(Int,Int)=>Int, g :(Int,Int)=>Int) :Int =
a.zip(b).map(f.tupled).reduce(g)
val a= List(1,2,3)
val b= List(4,5,6)
mergeReduce(a,b,_*_,_+_) // 32
mergeReduce(a,b,math.max,math.min) // 4
那么,您要替换的“内置”功能是什么?为什么要替换它们?
然后是没有map
,reduce
,zip
和tupled
的版本。
def mergeReduce(lsta :List[Int], lstb :List[Int]
,f :(Int,Int)=>Int, g :(Int,Int)=>Int) :Int = {
def merg(x :List[Int], y :List[Int], acc :List[Int] = Nil) :List[Int] =
if (x.isEmpty || y.isEmpty) acc.reverse
else merg(x.tail, y.tail, f(x.head,y.head) :: acc)
def reduc(z: List[Int]) :Int = z match {
case Nil => -1 //error
case i :: Nil => i
case a::b::c => reduc(g(a,b) :: c)
}
reduc(merg(lsta, lstb))
}
这使用.isEmpty
,.reverse
,.head
,.tail
和.unapply
(完成模式匹配的方法)。还是“内置”太多了?
答案 1 :(得分:0)
我认为这就是您要寻找的。它仅使用基本的List
操作即可一次完成合并和缩减操作:
def mergeReduce[T](a: List[T], b: List[T], merge: (T, T) => T, reduce: (T, T) => T): T = {
@tailrec
def loop(a: List[T], b: List[T], res: T): T =
(a, b) match {
case (a :: at, b :: bt) => loop(at, bt, reduce(res, merge(a, b)))
case _ => res
}
loop(a.tail, b.tail, merge(a.head, b.head))
}
如果其中一个列表为Nil
,这将失败;如果长度不相同,则将静默丢弃较长列表中的值。