Scala中嵌套列表的深度反转
我想在Scala中递归地反转列表列表.
我在Python中写了深层次的逆转,如下所示: def deepReverse(items): if type(items) == list: return [deepReverse(item) for item in reversed(items)] else: return items 我如何在Scala中做同样的事情?问题不在于算法 – 它是类型的东西,我是较新的. 我需要使用[T]或List [List [T]]的列表,或T的列表和Ts的列表的任何深度的功能.根据我在其他地方看到的一个例子,我试着做一个案例课.我不想要一个只返回Any并接受Any的函数;感觉就像作弊. case class NL[+T](val v : Either[List[NL[T]],T]) 尽管如此,我也不太清楚我的类型是否平衡.我是Scala的新手,但是我认为这将是一个完美的机会,可以把递归和打字弄乱. 解决方法
编写sschaef建议的类型类方法的版本实际上并不难,这将适用于任意嵌套列表:
trait Reverser[C] { def reverse(xs: C): C } implicit def rev[A](implicit ev: Reverser[A] = null) = new Reverser[List[A]] { def reverse(xs: List[A]) = Option(ev).map(r => xs map r.reverse).getOrElse(xs).reverse } def deepReverse[A](xs: A)(implicit ev: Reverser[A]): A = ev.reverse(xs) 我们的rev方法中的隐含参数ev证明A本身是可逆的,如果ev是null,这意味着它不是.如果我们有这样的证据表明A是可逆的,我们用它来扭转我们的List [A]的元素(这是地图正在做的),然后我们反转列表本身.如果我们没有这个证据(getOrElse的情况),我们可以反转列表. 我们可以像这样简洁地(但可能更有效地)写入rev: implicit def rev[A](implicit ev: Reverser[A] = null) = if (ev == null) { new Reverser[List[A]] { def reverse(xs: List[A]) = xs.reverse } } else { new Reverser[List[A]] { def reverse(xs: List[A]) = (xs map ev.reverse).reverse } } 要测试这两个版本之一,我们可以写下列内容: scala> deepReverse(List.tabulate(3)(identity)) res0: List[Int] = List(2,1,0) scala> deepReverse(List.tabulate(2,3) { case (a,b) => a + b }) res1: List[List[Int]] = List(List(3,2,1),List(2,0)) scala> deepReverse(List.tabulate(2,3,4,5,6) { | case (a,b,c,d,e) => a + b + c + d + e | }).head.head.head.head res2: List[Int] = List(15,14,13,12,11,10) 如预期 我应该补充说,以下是一个更常见的成语,就是在这样的情况下得到这个意思: trait ReverserLow { implicit def listReverser[A] = new Reverser[List[A]] { def reverse(xs: List[A]) = xs.reverse } } object ReverserHigh extends ReverserLow { implicit def nestedListReverser[A](implicit ev: Reverser[A]) = new Reverser[List[A]] { def reverse(xs: List[A]) = xs.map(ev.reverse).reverse } } import ReverserHigh._ 如果我们刚刚在同一级别写了listReverser和nestedListReverser,当我们尝试反转列表列表时,我们会收到以下错误: scala> deepReverse(List.tabulate(2,3)(_ + _)) <console>:12: error: ambiguous implicit values: both method listReverser... and method nestedListReverser... match expected type Reverser[List[List[Int]]] deepReverse(List.tabulate(2,3)(_ + _)) 优先考虑两者的标准方法是将较低优先级隐含在一个特征(WhateverLow)中,另一个在扩展该特征的对象(WhateverHigh)中.在这样一个相当简单的情况下,尽管如此,在上面的rev方法中使用默认参数技巧更为简洁(更清晰).但是,您更有可能在其他人的代码中看到其他版本. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 在 Angular 中 APP_INITIALIZER 的作用是什么
- Bootstrap3基础 栅格系统 1行最多12列
- Scala如何知道要调用的方法(命名参数)
- replace – 用Vim中文件中别处的寄存器或行范围的内容替换
- 在Bash命令提示符下添加git branch
- bootstrap datepicker 属性设置 以及方法和事件
- shell – 使用xargs将“find”目录mv到另一个目录中
- scala – java.lang.ClassNotFoundException,当我使用“spa
- 【K8S】K8S 1.18.2安装dashboard(基于kubernetes-dashboar
- angular – 如何在离子页面中定义可选的段参数?