Извлечь элементы из Option [Any] списка - PullRequest
0 голосов
/ 23 декабря 2018
scala> val a  = jsonMap.get("L2_ID")
a: Option[Any] = Some(List(24493, 22774, 23609, 20517, 22829, 23646, 22779, 23578, 22765, 23657))

Я хочу получить первый элемент списка, т. Е. 24493. Итак, попробовал следующий код:

scala> var b = a.map(_.toString)
b: Option[String] = Some(List(24493, 22774, 23609, 20517, 22829, 23646, 22779, 23578, 22765, 23657))

scala>

scala>  var c = b.map(_.split(",")).toList.flatten
c: List[String] = List(List(24493, " 22774", " 23609", " 20517", " 22829", " 23646", " 22779", " 23578", " 22765", " 23657)")

scala> c(0)
res34: String = List(24493

Это не возвращается, как ожидалось.Пожалуйста, предложите.

Ответы [ 3 ]

0 голосов
/ 23 декабря 2018

Я предлагаю вам использовать сопоставление с образцом.Чтобы защититься, я также добавил Try для защиты от случая, когда ваш json не является списком чисел.Приведенный ниже код возвращает Option[Int], и вы можете вызвать .getOrElse(0) для него - или другое значение по умолчанию, если хотите.

import scala.util.Try

val first = a match {
  case Some(h :: _) => Try(h.toString.toInt).toOption
  case _ => None
}
0 голосов
/ 23 декабря 2018

Итак, у вас есть Option и List внутри него.Затем scala> var b = a.map(_.toString) преобразует содержимое Option (a List) в String.Это не то, что вы хотите.Посмотрите на типы результатов ваших преобразований, они служат для того, чтобы предоставить вам довольно хорошие советы.b: Option[String], например, сообщает, что вы потеряли список ...

 a.map(_.map(_.toString))

имеет тип Option[List[String]] с другой стороны: вы преобразовали каждый элемент списка в строку.

Если вы просто ищете первый элемент, вам не нужно конвертировать их все.Что-то вроде этого подойдет:

 a
  .flatMap(_.headOption) // Option[Int], containing first element or None if list was empty or id a was None
  .map(_.toString) // convert Int inside of Option (if any) to String
  .getOrElse("")   // get the contents of the Option, or empty string if it was None
0 голосов
/ 23 декабря 2018

Если вы уверены, что это Some и что список не пустой, вы можете развернуть опцию и получить List[Int], используя .get.Затем вы можете получить доступ к первому элементу списка, используя .head:

val x: Option[List[Int]] = ???
x.get.head

Если вы не в REPL и не уверены, является ли это Some или None,и если у List есть какие-либо элементы, то использование

x.flatMap(_.headOption).getOrElse(yourDefaultValueEg0)

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

...