【问题标题】:List of Lists Circular Definition Scala列表列表循环定义 Scala
【发布时间】:2012-10-10 15:09:02
【问题描述】:

我有一个由整数定义的列表:

val ex: List[List[Int]] = List(List (1, 2, 3), List(4, 5, 6), List(7, 8 , 9), ex)

如何使用 scala 中的循环定义将列表列表的所有元素乘以 2?

编辑: 实体 X 的循环定义是有效地使用 X 来设置自己 X 的定义。

例子:

val ex1: List[List[Int]] = List(List(1,2,3), <call ex1 to multiply the elements by two>)

该示例将创建一个无限列表。很抱歉之前没有澄清。

谢谢!

【问题讨论】:

  • 什么是循环定义
  • 看到编辑后的帖子,对不起
  • 我还是不明白。请给出输入和预期输出。我不知道什么是“无限列表”
  • 我猜他的意思是递归
  • 詹姆斯,没有一个答案被标记为正确 - 他们都错过了标记吗?

标签: scala


【解决方案1】:

我不确定,但我认为您可能正在寻找 Streams,它类似于延迟定义的列表,并且该定义可以是递归的。这看起来像你想要的吗?

scala> val ex:Stream[List[Int]] = List(1,2,3) #:: ex.map( _ map (_*2) )
ex: Stream[List[Int]] = Stream(List(1, 2, 3), ?)

scala> ( ex take 5 ) foreach println
List(1, 2, 3)
List(2, 4, 6)
List(4, 8, 12)
List(8, 16, 24)
List(16, 32, 48)

或许

scala> val ex:Stream[List[Int]] = List(1,2,3) #:: ex.map( _ map (_+3) )
ex: Stream[List[Int]] = Stream(List(1, 2, 3), ?)

scala> ( ex take 5 ) foreach println
List(1, 2, 3)
List(4, 5, 6)
List(7, 8, 9)
List(10, 11, 12)
List(13, 14, 15)

【讨论】:

  • 啊,现在我看到 Luigi 给出了一个两部分的答案,第二部分是关于 Streams。不过,我会留下我的,因为我们对问题的解释不同,所以我们的解决方案也不同。
  • val ex 应该是 def ex 以避免循环引用
  • 这是一个编译错误scalakata.com/5095b810e4b093f3524f3435 至少在演示编译器中。
  • Guillaume,你的问题迫使我做一些研究;我写了问答here
【解决方案2】:
  1. 你不能有一个无限的List,因为它不是Scala 中的惰性数据结构,你将不可避免地耗尽内存。但是 Scala 有一个惰性结构 - Stream
  2. 您正在寻找的是iterate 函数。标准库中缺少它,所以这里有一个受Haskell 启发的实现(假设您使用的是 Scala 2.10):

    implicit class AnyFunctional [ A ] ( val a : A ) extends AnyVal {
      def iterate ( f : A => A ) : Stream[A] = a #:: (f(a) iterate f)
    }
    

    将它放在范围内,您就可以像这样使用它:

    scala> List(1,2,3) iterate (_.map(_*2)) take 3 toList
    warning: there were 1 feature warnings; re-run with -feature for details
    res7: List[List[Int]] = List(List(1, 2, 3), List(2, 4, 6), List(4, 8, 12))
    

【讨论】:

    【解决方案3】:

    如果我正确解释了您的问题,您希望这样做:

    val ex: List[List[Int]] = {
      val ex = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
      ex ++ ex
    }
    

    这不是一个循环定义,因为内部 ex 只是遮住了外部(如果使用不同的变量名会更清楚)。

    如果你真的想要一个递归定义,你需要使用一个惰性数据结构,比如Stream(你可以试试List,但你会得到一个NullPointerException)。所以你可以这样写:

    val ex: Stream[List[Int]] = 
      Stream(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) #::: (ex take 3)
    
    ex.toList // if it actually needs to be a List, which is probably doesn't
    

    #:::List 上的 ::: 的惰性 Stream

    如果您附加ex 而不是ex take 3,那么ex 将是无限的,您可以使用(ex take 6).toList 获取您的列表。

    编辑:在阅读@AmigoNico 对您的问题的解释(这可能是正确的解释 - 但谁知道!)之后,您也可以使用iterate 函数来执行此操作,例如

    List.iterate(List(1,2,3), 3)(_ map (_ * 2))
      // List(List(1, 2, 3), List(2, 4, 6), List(4, 8, 12))
    
    // or if you want it infinte:
    val xs = Stream.iterate(List(1,2,3))(_ map (_ * 2))
    (xs take 3).toList
      // result same as above
    

    【讨论】:

      猜你喜欢
      • 2020-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      • 1970-01-01
      • 2012-12-04
      • 2021-11-25
      • 1970-01-01
      相关资源
      最近更新 更多