在scala中创建重复的true / false列表

时间:2012-02-03 17:07:55

标签: scala

我想生成一个真/假值的Seq / List,我可以用一些输入压缩,以便相当于检查for循环索引是否是奇数/偶数。

有没有比

更好的方法
input.zip((1 to n).map(_ % 2 == 0))

input.zip(List.tabulate(n)(_ % 2 != 0))

我原以为(true, false).repeat(n/2)之类的东西更明显

6 个答案:

答案 0 :(得分:9)

使用@DaveGriffith's idea

input.zip(Stream.iterate(false)(!_))

或者,如果您在多个地方使用此模式:

def falseTrueStream = Stream.iterate(false)(!_)

input.zip(falseTrueStream)

这具有明显的优点,即不需要指定false-true列表的大小。

<强> 编辑:

当然,def falseTrueStream每次使用时都会创建true / false个对象的流,而@DanielCSobral mentioned会创建val val {1}}将导致对象保留在内存中(如果object位于Stream上,程序将结束)。

如果你有点邪恶并希望过早地优化它,你可以自己构建object TrueFalseStream extends Stream[Boolean] { val tailDefined = true override val isEmpty = false override val head = true override val tail = FalseTrueStream } object FalseTrueStream extends Stream[Boolean] { val tailDefined = true override val isEmpty = false override val head = false override val tail = TrueFalseStream } 个对象。

{{1}}

答案 1 :(得分:4)

如果你想要一个大小为n的交替真/假列表:

List.iterate(false, n)(!_)

那么你可以这样做:

val input = List("a", "b", "c", "d")
input.zip(List.iterate(false, input.length)(!_))
//List[(java.lang.String, Boolean)] = List((a,false), (b,true), (c,false), (d,true))

答案 2 :(得分:4)

在Haskell中有一个非常有用的功能 - cycle - 这对于这样的目的非常有用:

haskell> zip [1..7] $ cycle [True, False]
[(1,True),(2,False),(3,True),(4,False),(5,True),(6,False),(7,True)]

由于某种原因,Scala标准库没有它。您可以自己定义它,然后使用它。

scala> def cycle[A](s: Stream[A]): Stream[A] = Stream.continually(s).flatten
cycle: [A](s: Stream[A])Stream[A]

scala> (1 to 7) zip cycle(Stream(true, false))
res13: scala.collection.immutable.IndexedSeq[(Int, Boolean)] = Vector((1,true), (2,false), (3,true), (4,false), (5,true), (6,false), (7,true))

答案 3 :(得分:2)

你想要

input.indices.map(_%2==0)

答案 4 :(得分:1)

我无法想出更简单的事情(这远非简单):

(for(_ <- 1 to n/2) yield List(true, false)).flatten

(1 to n/2).foldLeft(List[Boolean]()) {(cur,_) => List(true, false) ++ cur}

注意奇怪n

但根据您的要求,您可能希望拥有 lazy

def oddEven(init: Boolean): Stream[Boolean] = Stream.cons(init, oddEven(!init))

......它永远不会结束(尝试:oddEven(true) foreach println)。现在你可以随心所欲:

oddEven(true).take(10).toList

答案 5 :(得分:0)

  

...以便相当于检查for循环索引是否为奇数/偶数。

我忽略了您的具体要求,并以不同的方式解决您的主要问题。 您可以创建自己的控制功能,如下所示:

def for2[A,B](xs: List[A])(f: A => Unit, g: A => Unit): Unit = xs match {
    case (y :: ys) => {
      f(y)
      for2(ys)(g, f)
    }
    case _ => Unit
}

测试

> for2(List(0,1,2,3,4,5))((x) => println("E: " + x), (x) => println("O: " + x))
E: 0
O: 1
E: 2
O: 3
E: 4
O: 5