Количество Count строк, которые могут быть преобразованы в Int в списке
Например, мой ввод:
scala> val myList = List("7842", "abf45", "abd", "56")
myList: List[String] = List(7842, abf45, abd, 56)
7842
и 56
можно преобразовать в Int
; поэтому мой ожидаемый результат равен 2
. Мы можем предположить, что отрицательных целых чисел не бывает, поэтому -67
невозможно.
Это то, что у меня есть до сих пор:
scala> myList.map(x => Try(x.toInt).getOrElse(-1)).count(_ > -1)
res15: Int = 2
Это должно работать правильно, но я чувствую, что мне не хватает более элегантного и читаемого решения, потому что все, что мне нужно сделать, - это количество успехов.
Ответы
Ответ 1
Я бы предостерег от использования обработки исключений (например, Try
) в потоке управления - он очень медленный.
Здесь решение, которое использует идиоматические операции коллекции Scala, работает хорошо и не будет считать отрицательные числа:
scala> val myList = List("7842", "abf45", "abd", "56")
myList: List[String] = List(7842, abf45, abd, 56)
scala> myList.count(_.forall(_.isDigit))
res8: Int = 2
EDIT: @immibis указал, что это не будет определять строки чисел, которые превышают Integer.MaxValue
. Если это вызывает беспокойство, я бы рекомендовал один из следующих способов:
import scala.util.Try
myList.count(x => Try(x.toInt).filter(_ >= 0).isSuccess)
или, если вы хотите сохранить производительность моего первого ответа, продолжая обрабатывать этот край:
import scala.util.Try
myList.count(x => x.forall(_.isDigit) && Try(x.toInt).filter(_ >= 0).isSuccess)
Ответ 2
Это немного короче:
myList.count(x => Try(x.toInt).isSuccess)
Обратите внимание, что это решение будет обрабатывать любую строку, которая может быть преобразована в целое число через .toInt
, включая отрицательные числа.
Ответ 3
Вы можете рассмотреть метод string.matches
с регулярным выражением, чтобы соответствовать только положительным целям:
val myList = List("7842", "abf45", "abd", "-56")
// myList: List[String] = List(7842, abf45, abd, -56)
myList.count(_.matches("\\d+"))
// res18: Int = 1
Если отрицательные целые числа нужно подсчитать (и учитывать возможные знаки +/-):
myList.count(_.matches("[+-]?\\d+"))
// res17: Int = 2
Ответ 4
Начиная с Scala 2.13
и представляя String::toIntOption
, мы можем подсчитывать элементы ("34"
/"2s3"
), для которых определено применение toIntOption
(Some(34)
/None
) (true/false
):
List("34", "abf45", "2s3", "56").count(_.toIntOption.isDefined) // 2