Как использовать Scala reduLeft на тематических классах? - PullRequest
3 голосов
/ 01 февраля 2012

Я понимаю, как использовать reduLeft в простых списках целых чисел, но пытаюсь использовать, если в случае объектов класса не удается.

Предположим, у меня есть:

  case class LogMsg(time:Int, cat:String, msg:String)
  val cList = List(LogMsg(1,"a", "bla"), LogMsg(2,"a", "bla"), LogMsg(4,"b", "bla"))

и я хочу найти наибольшую разницу во времени между LogMsgs. Я хочу сделать что-то вроде:

cList.reduceLeft((a,b) => (b.time - a.time)

что, конечно, не работает.
Первая итерация ReduceLeft сравнивает первые два элемента, оба из которых имеют тип LogMsg. После этого он сравнивает следующий элемент (LogMsg) с результатом первой итерации (Int).

У меня просто неправильный синтаксис или я должен делать это по-другому?

Ответы [ 3 ]

6 голосов
/ 02 февраля 2012

Моя попытка:

cList.sliding(2).map(t => t(1).time - t(0).time).max

Еще одна вещь, которая пришла мне в голову: поскольку LogMsg является классом case, мы можем воспользоваться преимуществами сопоставления с образцом:

cList.sliding(2).collect{
  case List(LogMsg(a, _, _), LogMsg(b, _, _)) => b - a}.
max
6 голосов
/ 01 февраля 2012

Я бы, наверное, сделал что-то вроде этого:

(cList, cList.tail).zipped.map((a, b) => b.time - a.time).max

Вам нужно заранее проверить, что cList имеет как минимум 2 элемента.

reduceLeft нельзя использовать для возврата наибольшей разницы, потому что он всегда возвращает тип сокращаемого списка, т.е. LogMsg в этом случае, и вы запрашиваете Int.

0 голосов
/ 01 февраля 2012

Я бы порекомендовал вам использовать foldLeft, то есть reduceLeft, позволяющий вам инициализировать результаты.

val head::tail = cList
tail.foldLeft((head.time, 0)) ((a,b) => (b.time, math.max(a._2,b.time-a._1)))._2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...