加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 惯用语“直到”集合更新

发布时间:2020-12-16 10:04:19 所属栏目:安全 来源:网络整理
导读:场景: val col: IndexedSeq[Array[Char]] = for (i - 1 to n) yield { val x = for (j - 1 to m) yield 'x' x.toArray} 这是一个相当简单的char矩阵. toArray曾经允许更新. var west = last.x - 1 while (west = 0 arr(last.y)(west) == '.') { arr(last.y)
场景:

val col: IndexedSeq[Array[Char]] = for (i <- 1 to n) yield {
   val x = for (j <- 1 to m) yield 'x'
   x.toArray
}

这是一个相当简单的char矩阵. toArray曾经允许更新.

var west = last.x - 1
  while (west >= 0 && arr(last.y)(west) == '.') {
      arr(last.y)(west) = ch;
      west -= 1;
  }

这是更新所有.到ch,直到找到非点char.

通常,更新直到满足停止条件,步骤未知.

什么是惯用的等价物?

结论

它是可行的,但权衡不值得,当集合允许更新时,表达语法会失去很多性能.

解决方法

你对“更清洁,更惯用”的解决方案的愿望当然有点模糊,因为它为主观性留下了很大的空间.一般来说,我认为尾递归更新例程更惯用,但如果你更熟悉非函数式编程风格,它可能不是“更干净”.我想出了这个:

@tailrec
def update(arr:List[Char],replace:Char,replacement:Char,result:List[Char] = Nil):List[Char] = arr match {
    case `replace` :: tail =>
        update(tail,replace,replacement,replacement :: result)
    case _ => result.reverse ::: arr
}

这需要一个内部序列(假设一个List用于更容易的模式匹配,因为Arrays可以简单地转换为列表),并且用递归替换替换char.

然后,您可以使用map更新外部序列,如下所示:

col.map { x => update(x,'.',ch) }

另一个更可重用的替代方法是编写自己的mapUntil,或使用在补充库中实现的一个(Scalaz可能有类似的东西).我想出的那个看起来像这样:

def mapUntil[T](input:List[T])(f:(T => Option[T])) = {
    @tailrec
    def inner(xs:List[T],result:List[T]):List[T] = xs match {
        case Nil => Nil
        case head :: tail => f(head) match {
            case None => (head :: result).reverse ::: tail
            case Some(x) => inner(tail,x :: result)
        }
    }

    inner(input,Nil)
}

它与常规映射调用相同,只是一旦传递的函数返回None,它就会停止,例如,

mapUntil(List(1,2,3,4)) {
    case x if x >= 3 => None
    case x => Some(x-1)
}

会导致

List[Int] = List(0,1,4)

如果你想看看Scalaz,this answer可能是一个很好的起点.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读