Scala列表的迭代

3
我有一个scala模板中的字符串列表,涉及到play框架。
我想一次遍历列表的前一半,然后在第二次遍历时遍历列表的后一半。
我不确定如何编写高效的迭代器来实现这个目标。

我尝试过
@for(i <- 0 until list.length/2 ) {list(i) }
然后是第二个循环

@for(i <- list.length/2+1 until list.length ) 
 { list(i) } 

这个方法可以用,但是复杂度较高。
后来我尝试了:
  @defining(list.size) { size => 
    @for(i <- 0 until size/2) 
    {list(i) }
  }

现在看起来它运行良好。

1
请修改您上面的问题,即使您已经有了一个看起来很好的答案。 - Jeremy D
我刚刚尝试了@for(i <- 0 until list.length/2 ) {list(i)},然后是第二个循环@for(i <- list.length/2+1 until list.length ) {list(i)}。目前看来这似乎运行良好。 - user2694377
3个回答

5
这里有一种方法。
scala> List("a","b","c","d","e")
res0: List[String] = List(a, b, c, d, e)

scala> res0.splitAt(res0.size/2)
res1: (List[String], List[String]) = (List(a, b),List(c, d, e))

scala> res1._1.foreach(println(_))
a
b

scala> res1._2.foreach(println(_))
c
d
e

是的。这个方法可以行得通,但我不想再创建另一个列表。我刚刚在for循环中找到了迭代列表一半元素的语法。@for(i <- 0 until list.length/2 ) {} 然后从list.length/2+1直到list.length。 - user2694377
1
@user2694377:创建2个新集合的成本为O(N),使用索引迭代List的成本为O(N^2)。这真的不是一个好主意。如果您不想复制集合,可以使用带有droptakeIterator - senia
好的。谢谢。不好意思,我没有注意到它是O(n^2)。感谢您指出。 - user2694377

1
使用滑动来创建迭代器。
scala> val input = List(1, 2, 3)
input: List[Int] = List(1, 2, 3)

scala> val step = (input.length + 1 ) / 2
step: Int = 2

scala> val sliding = input.sliding(step, step)
sliding: Iterator[List[Int]] = non-empty iterator

scala> val left = sliding.next()
left: List[Int] = List(1, 2)

scala> val right = sliding.next()
right: List[Int] = List(3)

scala> left.foreach(println)
1
2

scala> right.foreach(println)
3

或使用 take & drop,

scala> val input = List(1, 2, 3)
input: List[Int] = List(1, 2, 3)

scala> val step = (input.length + 1 ) / 2
step: Int = 2

scala> input.take(step).foreach(println)
1
2

scala> input.drop(step).foreach(println)
3

0

迭代器 可能是一个不错的选择。

scala> val list = List(1,2,3,4,5,6)
list: List[Int] = List(1, 2, 3, 4, 5, 6)

scala> val iterator = list.toIterator
iterator: Iterator[Int] = non-empty iterator

scala> val half = (0 until list.size / 2)
half: scala.collection.immutable.Range = Range(0, 1, 2)

scala> val left = (list.size / 2 until list.size)
left: scala.collection.immutable.Range = Range(3, 4, 5)

scala> half foreach { x => println(x + ":" + iterator.next) }
0:1
1:2
2:3

scala> left foreach { x => println(x + ":" + iterator.next) }
3:4
4:5
5:6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接