简体   繁体   English

如何在 Scala 范围内实现多步

[英]How can I achieve multiple step in scala range

How can I achieve multiple step in scala range如何在 Scala 范围内实现多步

Like this: var r = 1 to 100 by (2, 3, 4)像这样:var r = 1 to 100 by (2, 3, 4)

And the last number 4, if there are more to step, will be the repeat step.最后一个数字 4,如果还有更多的步骤,将是重复步骤。

or bonus: something like with mode或奖励:类似于模式
1. var = 1 to 100 by (2, 3, 4) review // review steps from 2, 3, 4 again. 1. var = 1 to 100 by (2, 3, 4) review // 再次回顾 2, 3, 4 的步骤。
2. var = 1 to 100 by (2, 3, 4) last // use last number as final steps. 2. var = 1 to 100 by (2, 3, 4) last // 使用最后一个数字作为最后一步。
3. var = 1 to 100 by (2, 3, 4) random // use steps randomly within these numbers. 3. var = 1 to 100 by (2, 3, 4) random // 在这些数字中随机使用步骤。
4. var = 1 to 100 by (2, 3, 4) reverse // use steps in reverse and reverse manner. 4. var = 1 to 100 by (2, 3, 4) reverse // 以反向和反向方式使用步骤。

import scala.collection.immutable.Stream
import scala.collection.mutable.ListBuffer
import scala.util.Random

abstract class RangeX(override val head: Int, val end: Int, var step: Int) extends Stream[Int] {
  override val tailDefined = false
  override val isEmpty = head > end

  def by(steps: Seq[Int]) = {
    StepVariant(this, steps)
  }

  def byGroup(steps: Seq[Int]) = {
    StepVariantInGroup(this, steps)
  }

  def steps(steps: Seq[Int])(fn_steps: (Seq[Int], Int) => Int) = {
    var acc = new ListBuffer[Int]()
    this.zipWithIndex.foreach {
      case (i, idx) =>
        acc += i
        this.step = fn_steps(steps, idx)
    }
    acc.toList
  }

  def stepsByGroup(steps: Seq[Int])(fn_steps: (Seq[Int], Int) => Int) = {

    val ls = this.steps(steps)(fn_steps)
    var acc = new ListBuffer[List[Int]]()
    val lidx = ls.length - 1
    (1 to lidx).foreach { i =>
      acc += (ls(i - 1) to ls(i) - 1).toList
    }

    acc.toList
  }

  case class StepVariant(streams: RangeX, steps: Seq[Int]) {
    def repeating_steps = streams.steps(steps)(RangeX.repeating_steps)
    def repeat_last_step = streams.steps(steps)(RangeX.repeat_last_step)
    def random_steps = streams.steps(steps)(RangeX.random_steps)
    def reversing_steps = streams.steps(steps)(RangeX.reversing_steps)

  } 

  case class StepVariantInGroup(streams: RangeX, steps: Seq[Int]) {
    def repeating_steps = streams.stepsByGroup(steps)(RangeX.repeating_steps)
    def repeat_last_step = streams.stepsByGroup(steps)(RangeX.repeat_last_step)
    def random_steps = streams.stepsByGroup(steps)(RangeX.random_steps)
    def reversing_steps = streams.stepsByGroup(steps)(RangeX.reversing_steps)
  }

} 


class RangeSlaveX(_head: Int, _end: Int, _step: Int, val master: RangeX) extends RangeX(_head, _end, _step) {
  override def tail = if (isEmpty) Stream.Empty else new RangeSlaveX(head + master.step, end, master.step, master)
}

class RangeMasterX(_head: Int, _end: Int, _step: Int) extends RangeX(_head, _end, _step) {
  override def tail = if( isEmpty ) Stream.Empty else new RangeSlaveX(head + step, end, step, this)
}

object RangeX {
  implicit def toRangeX(range: Range): RangeX = new RangeMasterX(range.start, range.end, range.step)
  def apply(head: Int, end: Int, step: Int) = new RangeMasterX(head, end, step)

  def repeating_steps(steps: Seq[Int], idx: Int): Int = {
    val size = steps.size
    steps( idx % size )
  }

  def repeat_last_step(steps: Seq[Int], idx: Int): Int = {
    val len = steps.length - 1
    steps(if( idx >= len) len else idx)
  }

  def random_steps(steps: Seq[Int], idx: Int): Int = {
    Random.shuffle(steps).head
  }

  def reversing_steps(steps: Seq[Int], idx: Int): Int = {
    val size = steps.size
    val lidx = size - 1
    val forward = ((idx / size) % 2) == 0

    if(forward) {
      steps( idx % size )
    } else {
      steps( lidx - (idx % size))
    }
  }

}


scala> import RangeX._
import RangeX._

Method Chaining Way: - by and byGroup方法链方式:- by 和 byGroup

scala> 1 to 20 byGroup Seq(1, 2, 3) reversing_steps  
res0: List[List[Int]] = List(List(1), List(2, 3), List(4, 5, 6), List(7, 8, 9), List(10, 11), List(12), List(13), List(14, 15), List(16, 17, 18))

scala> 1 to 20 byGroup Seq(1, 2, 3) random_steps  
res1: List[List[Int]] = List(List(1, 2, 3), List(4, 5), List(6, 7, 8), List(9, 10), List(11, 12), List(13, 14, 15), List(16, 17, 18))

scala> 1 to 20 byGroup Seq(1, 2, 3) repeating_steps  
res2: List[List[Int]] = List(List(1), List(2, 3), List(4, 5, 6), List(7), List(8, 9), List(10, 11, 12), List(13), List(14, 15), List(16, 17, 18), List(19))

scala> 1 to 20 byGroup Seq(1, 2, 3) repeat_last_step    
res3: List[List[Int]] = List(List(1), List(2, 3), List(4, 5, 6), List(7, 8, 9), List(10, 11, 12), List(13, 14, 15), List(16, 17, 18))

scala> 1 to 20 by Seq(1, 2, 3) reversing_steps  
res4: List[Int] = List(1, 2, 4, 7, 10, 12, 13, 14, 16, 19)

scala> 1 to 20 by Seq(1, 2, 3) random_steps  
res5: List[Int] = List(1, 2, 3, 6, 8, 11, 13, 15, 17, 19, 20)

scala> 1 to 20 by Seq(1, 2, 3) repeating_steps  
res6: List[Int] = List(1, 2, 4, 7, 8, 10, 13, 14, 16, 19, 20)

scala> 1 to 20 by Seq(1, 2, 3) repeat_last_step  
res7: List[Int] = List(1, 2, 4, 7, 10, 13, 16, 19)

Functional Way: - steps and stepsByGroup功能方式:-steps 和stepsByGroup

scala> (1 to 20).steps(Seq(1, 2, 3))(reversing_steps)
res12: List[Int] = List(1, 2, 4, 7, 10, 12, 13, 14, 16, 19)

scala> (1 to 20).steps(Seq(1, 2, 3))(random_steps)
res13: List[Int] = List(1, 4, 6, 8, 10, 12, 14, 16, 17, 18, 20)

scala> (1 to 20).steps(Seq(1, 2, 3))(repeating_steps)
res11: List[Int] = List(1, 2, 4, 7, 8, 10, 13, 14, 16, 19, 20)

scala> (1 to 20).steps(Seq(1, 2, 3))(repeat_last_step)
res15: List[Int] = List(1, 2, 4, 7, 10, 13, 16, 19)


scala> (1 to 20).stepsByGroup(Seq(1, 2, 3))(reversing_steps)
res17: List[List[Int]] = List(List(1), List(2, 3), List(4, 5, 6), List(7, 8, 9), List(10, 11), List(12), List(13), List(14, 15), List(16, 17, 18))

scala> (1 to 20).stepsByGroup(Seq(1, 2, 3))(random_steps)
res18: List[List[Int]] = List(List(1, 2), List(3, 4), List(5), List(6), List(7), List(8, 9), List(10, 11), List(12, 13), List(14, 15, 16), List(17, 18, 19))

scala> (1 to 20).stepsByGroup(Seq(1, 2, 3))(repeating_steps)
res19: List[List[Int]] = List(List(1), List(2, 3), List(4, 5, 6), List(7), List(8, 9), List(10, 11, 12), List(13), List(14, 15), List(16, 17, 18), List(19))

scala> (1 to 20).stepsByGroup(Seq(1, 2, 3))(repeat_last_step)
res20: List[List[Int]] = List(List(1), List(2, 3), List(4, 5, 6), List(7, 8, 9), List(10, 11, 12), List(13, 14, 15), List(16, 17, 18))

How's my revise implementation ^.我的修订实施情况如何 ^。 Seed idea from @Piro implementation link .来自@Piro 实现链接的种子想法。 Thx.谢谢。

Step Variants步骤变体
review is repeating_steps审查正在重复_步骤
last is repeat_last_step最后是repeat_last_step
random is random_steps随机是 random_steps
reverse is reversing_steps反向是reversing_steps

I wish Sir Martin Odersky add these kind of Range features by(Seq(1,2,3)) *_steps and byGroup(Seq(1,2,3)) *_steps in next Scala release :)我希望 Martin Odersky 爵士在下一个 Scala 版本中添加这些范围功能by(Seq(1,2,3)) *_stepsbyGroup(Seq(1,2,3)) *_steps :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM