Iterating circular way

后端 未结 4 1353
甜味超标
甜味超标 2021-01-11 11:14

I need iterate through a List but circular way. I need too add new elements to the list and iterate over all elements (olds and news elements), How I do it? Is there any dat

相关标签:
4条回答
  • 2021-01-11 11:25
    def forever:Stream[Int] = Stream(1,2,3) append forever
    
    0 讨论(0)
  • 2021-01-11 11:47

    This sort of thing really deserves to be in standard stream library, but doesn't appear to be. dbryne's answer with a stream works well, or if you prefer it in for-comprehension form

    val listToRepeat:List[Foo]
    val forever:Stream[Foo] = for(x<-Stream.continually(1); y<-listToRepeat) yield y
    

    The first stream generator keeps things going forever even though you are ignoring the value. The second generator gets implicitly flattened into the infinite stream you want.

    0 讨论(0)
  • 2021-01-11 11:48

    One option is to use the Stream class to create a lazy, circular, infinite sequence:

    scala> val values = List(1, 2, 3)
    values: List[Int] = List(1, 2, 3)
    
    scala> Stream.continually(values.toStream).flatten.take(9).toList
    res2: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3)
    

    or this way:

    val values = List(1, 2, 3)
    
    def circularStream(values: List[Int],
                       remaining: List[Int] = List()): Stream[Int] = {
    
      if (remaining.isEmpty)
        circularStream(values,values)
      else
        Stream.cons(remaining.head, circularStream(values, remaining.drop(1)))
    }
    
    circularStream(values).take(9).toList //Same result as example #1
    
    0 讨论(0)
  • 2021-01-11 11:50

    I think maybe this is what you want; the ability to add new elements to your list even as you are iterating it. The code is ugly but it seems to work.

    import scala.collection.mutable.Queue
    
    class Circular[A](list: Seq[A]) extends Iterator[A]{
    
      val elements = new Queue[A] ++= list
      var pos = 0
    
      def next = {
        if (pos == elements.length) 
          pos = 0
        val value = elements(pos)
        pos = pos + 1
        value
      }
    
      def hasNext = !elements.isEmpty
      def add(a: A): Unit = { elements += a }
      override def toString = elements.toString
    
    }
    

    You can use it like this:

    scala> var circ = new Circular(List(1,2))
    res26: Circular[Int] = Queue(1,2)
    scala> circ.next
    res27: Int = 1
    scala> circ.next
    res28: Int = 2
    scala> circ.next
    res29: Int = 1
    scala> circ.add(5)
    scala> circ.next
    res30: Int = 2
    scala> circ.next
    res31: Int = 5
    scala> circ
    res32: Circular[Int] = Queue(1,2,5)
    
    0 讨论(0)
提交回复
热议问题