How do you rotate (circular shift) of a Scala collection

后端 未结 11 1732
盖世英雄少女心
盖世英雄少女心 2020-12-19 03:40

I can do this quite easily, and cleanly, using a for loop. For instance, if I wanted to traverse a Seq from every element back to itself I would do the

11条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-19 04:07

    Another tail-recursive approach. When I benchmarked it with JMH it was about 2 times faster than solution based on drop/take:

    def rotate[A](list: List[A], by: Int): List[A] = {
    
        @tailrec
        def go(list: List[A], n: Int, acc: List[A]): List[A] = {
    
          if(n > 0) {
            list match {
              case x :: xs => go(xs, n-1, x :: acc)
            }
          } else {
            list ++ acc.reverse
          }
    
        }
    
        if (by < 0) {
          go(list, -by % list.length, Nil)
        } else {
          go(list, list.length - by % list.length, Nil)
        }    
    }
    
    //rotate right
    rotate(List(1,2,3,4,5,6,7,8,9,10), 3) // List(8, 9, 10, 1, 2, 3, 4, 5, 6, 7) 
    
    //use negative number to rotate left
    rotate(List(1,2,3,4,5,6,7,8,9,10), -3) // List(4, 5, 6, 7, 8, 9, 10, 1, 2, 3)
    

提交回复
热议问题