Тип коллекции Scala для фильтра

Предположим, что у вас есть List(1,"1"), он имеет тип List[Any], что, конечно, правильно и ожидаемо. Теперь, если я сопоставлю список таким образом

scala> List(1, "1") map {
     |   case x: Int => x
     |   case y: String => y.toInt
     | }

результирующий тип — List[Int], что также ожидается. Мой вопрос заключается в том, есть ли эквивалент карты для фильтра, потому что следующий пример приведет к списку [Any]. Это возможно? Я предполагаю, что это можно решить во время компиляции и, возможно, не во время выполнения?

scala> List(1, "1") filter {
     |   case x: Int => true
     |   case _ => false
     | }

person Joa Ebert    schedule 07.02.2010    source источник


Ответы (3)


Скала 2.9:

scala> List(1, "1") collect {
     |   case x: Int => x
     | }
res0: List[Int] = List(1)
person Daniel C. Sobral    schedule 07.02.2010

Для тех, кто натыкается на этот вопрос и задается вопросом, почему ответ, получивший наибольшее количество голосов, не работает для них, имейте в виду, что метод partialMap был переименован в collect перед финальным выпуском Scala 2.8. Попробуйте это вместо этого:

scala> List(1, "1") collect {
     |   case x: Int => x
     | }
res0: List[Int] = List(1)

(Это действительно должен быть комментарий к замечательному ответу Дэниела С. Собрала, но мне, как новому пользователю, пока не разрешено комментировать.)

person Mark Tye    schedule 11.02.2011

Что касается вашего измененного вопроса, если вы просто используете охрану в случае, состоящем из вашей частичной функции, вы получаете фильтрацию:

scala> val l1 = List(1, 2, "three", 4, 5, true, 6)
l1: List[Any] = List(1, 2, three, 4, 5, true, 6)

scala> l1.partialMap { case i: Int if i % 2 == 0 => i }
res0: List[Int] = List(2, 4, 6)
person Randall Schulz    schedule 08.02.2010
comment
Почему это возможно только с охранником? - person Joa Ebert; 09.02.2010
comment
Извините, это был очень глупый комментарий. Но почему filter() не генерирует результат как partialMap? - person Joa Ebert; 09.02.2010
comment
@Joa filter не меняет тип коллекции, потому что не изменяет ее элементы. - person Daniel C. Sobral; 09.02.2010
comment
Ну, фильтр просто принимает предикат, который не дает компилятору ничего для вывода типа результата. Принимая во внимание, что с частичной функцией она может использовать типы результатов всех случаев и вычислять верхнюю границу этих типов как общий тип частичной функции. - person Randall Schulz; 09.02.2010