Scala генерирует данные временных рядов с использованием внешнего значения - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь сгенерировать массив / список данных из start_time, поэтому мой код

var temp = parse_time

// for (i <- 1 to 10) yield temp.plusSeconds(600) // method 1

val max = 10
Range (0, max).map( _ => (temp.plusSeconds(600))) // method 2

Оба метода приведут к одному и тому же результату с данными внутри массива без каких-либо дополнительных изменений.

Может ли кто-нибудь помочь мне понять, почему и как я могу это исправить?

Ответы [ 3 ]

0 голосов
/ 27 июня 2018
List.tabulate(max)(i => temp.plusSeconds(600 * i))
0 голосов
/ 27 июня 2018

Поскольку .plusSeconds возвращает новое значение, а не изменяет исходное значение, вы получаете все результаты, плюс 600.

Вот пример LocalDateTime или OffsetDateTime

scala> import java.time.LocalDateTime
import java.time.LocalDateTime

scala> val temp = LocalDateTime.now
temp: java.time.LocalDateTime = 2018-06-26T17:31:36.858

scala> Range (0, 10).map( _ => (temp.plusSeconds(600)))
res1: scala.collection.immutable.IndexedSeq[java.time.LocalDateTime] = Vector(
     2018-06-26T17:41:36.858, 
     2018-06-26T17:41:36.858, 
     2018-06-26T17:41:36.858, 
     2018-06-26T17:41:36.858, 
     2018-06-26T17:41:36.858, 
     2018-06-26T17:41:36.858, 
     2018-06-26T17:41:36.858, 
     2018-06-26T17:41:36.858, 
     2018-06-26T17:41:36.858, 
     2018-06-26T17:41:36.858)

Если вы хотите инкрементное .plusSeconds использование, может использовать шаблон аккумулятора,

scala>     def add(start: Int, end: Int, date: LocalDateTime, dates: List[LocalDateTime]): List[LocalDateTime] = {
     |       if (  start == end ) dates
     |       else {
     |         val newDate = date.plusSeconds(600)
     |         add(start + 1, end, newDate, dates :+ newDate)
     |       }
     |     }
add: (start: Int, end: Int, date: java.time.LocalDateTime, dates: List[java.time.LocalDateTime])List[java.time.LocalDateTime]

scala> add(0, 10, LocalDateTime.now(), List.empty)
res19: List[java.time.LocalDateTime] = List(
2018-06-26T18:10:23.055, 
2018-06-26T18:20:23.055, 
2018-06-26T18:30:23.055, 
2018-06-26T18:40:23.055, 
2018-06-26T18:50:23.055, 
2018-06-26T19:00:23.055, 
2018-06-26T19:10:23.055, 
2018-06-26T19:20:23.055, 
2018-06-26T19:30:23.055, 
2018-06-26T19:40:23.055)

Или вы можете использовать List.iterate, который также в основном использует шаблон изменяемого аккумулятора.

  def iterate[A](start: A, len: Int)(f: A => A): CC[A] = {
    val b = newBuilder[A]
    if (len > 0) {
      b.sizeHint(len)
      var acc = start
      var i = 1
      b += acc

      while (i < len) {
        acc = f(acc)
        i += 1
        b += acc
      }
    }
    b.result()
  }
0 голосов
/ 27 июня 2018

Если вы хотите сгенерировать следующую запись из предыдущей (начиная с temp), попробуйте List.iterate:

List.iterate(temp, max)(_.plusSeconds(600))

Вот что он делает для целых чисел:

List.iterate(42, 10)(_ + 600)

производит:

List(42, 642, 1242, 1842, 2442, 3042, 3642, 4242, 4842, 5442)

Вот еще один пример с java.time.LocalDateTime:

List.iterate(LocalDateTime.now(), 10)(_.plusSeconds(600)) foreach println

Выход:

2018-06-27T12:52:53.237
2018-06-27T13:02:53.237
2018-06-27T13:12:53.237
2018-06-27T13:22:53.237
2018-06-27T13:32:53.237
2018-06-27T13:42:53.237
2018-06-27T13:52:53.237
2018-06-27T14:02:53.237
2018-06-27T14:12:53.237
2018-06-27T14:22:53.237
...