Класс сортировки по узлу из его поля JsValue - PullRequest
0 голосов
/ 02 марта 2020

У меня есть последовательность случая класса A (id: UUID, профиль: String, данные: JsValue)

Я хочу отсортировать последовательность по updated из данных JsValue поле

поле данных выглядит следующим образом

{
 "doors":2,
 "color":"Black",
 "updated":"2019-09-24T15:59:21+0200",
 "username":"John",
 "year":2016
}

Я пытался sequenceOfA.sortWith(_.data \ "updated" < _.data \ "updated"), но это не работает, потому что <не является членом JsLookupResult игры </p>

Приведение его к Строка тоже не работает

sequenceOfA.sortWith((_.data \ "updated").as[String] < (_.data \ "updated").as[String])

Какой самый идиоматический c способ сделать это в Scala?

Ответы [ 2 ]

0 голосов
/ 03 марта 2020

Потенциальное решение может быть:

// Input is Seq[A] i.e val input: Seq[A]
// ConvertToTimestamp is a method which takes time as string and returns timestamp. 
//This is required since time is in string and also timezones are involved. 
//So this method will convert time string to UTC time(in epochs)
// def convertToTimeStamp(time: String): Long

val updated: Seq[Long] = A.map(value => (value.data \ "updated").as[String]).map(x => convertToTimestamp(x)) // fetch value 

val pairs = input zip updated // List of ordered tuple

val sortedInput = pairs.sort(sortBy(pair => pair._2)).map(_._1).toSeq // sort using timestamp

В приведенном выше решении предполагается, что поле updated не является пустым. Если в случае вводимых данных оно пустое, измените функцию, в которой мы анализируем это поле (при вычислении значения updated, как показано выше, чтобы иметь значение по умолчанию на основе требования (либо 0, если вы хотите, чтобы такие записи были первыми, либо * 1006) * если вы хотите, чтобы эти записи были последними). ​​

Дайте мне знать, если это поможет !!

0 голосов
/ 03 марта 2020

Что вам нужно, это обработать отсутствующее поле. Это можно сделать с помощью более безопасного подхода с явной обработкой:

  sequenceOfA.sortWith { case (left, right) =>
    val leftUpdate = (left.data \ "update").validate[String].asOpt
    val rightUpdate = (right.data \ "update").validate[String].asOpt
    leftUpdate -> rightUpdate match {
      case (Some(left), Some(right)) => left < right
      case (None, Some(_)) => true // objects with `update` absent field goes first 
      case (Some(_), None) => false // objects with `update` present field goes after absent field
    }
  }

Или просто вызовите метод get, который может вызвать исключение - что крайне не рекомендуется:

sequenceOfA.sortWith((m \ "updated").as[String].get < (_.data \ "updated").as[String].get)

Надежда это помогает!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...