2013-10-25 2 views
2

Предположим, что у нас есть список некоторых значений int (положительный и отрицательный), и у нас есть задача удвоить только положительные значения. Вот фрагмент кода, который производит желаемый результат:Функция терминала для коллекций в scala

val list: List[Int] = .... 

    list.filter(_ > 0).map(_ * 2) 

До сих пор так хорошо, но что, если список очень большой размер N. Имеет ли программа перебирает N раз на функцию фильтра, а затем N раз на функции карте ?

Как известно Scala, когда пришло время пройти список в цикле и применить все материалы для фильтрации и отображения? Что будет результатом (в терминах перебора списка), если мы, например, сгруппируем исходный список с помощью функции идентификации (чтобы избавиться от дубликатов) и примените функцию карты?

ответ

2

Выполняет ли программа итерации N раз по функции фильтра, а затем N раз на карте функция?

Да, для List вместо этого вы должны использовать withFilter. Из withFilter документа:

Note: the difference between `c filter p` and `c withFilter p` is that 
     the former creates a new collection, whereas the latter only 
     restricts the domain of subsequent `map`, `flatMap`, `foreach`, 
     and `withFilter` operations. 
+0

что, если мы делаем 'partition', а затем манипулировать на двух коллекций, созданных (для например, 'zip',' map' и т. д.). Можно ли каждый раз перебирать коллекцию? – maks

3

ли данная программы итерация п раз на функции фильтра, а затем п раз на функции карты?

Да. Используйте представление, чтобы сделать операции с коллекциями ленивыми. Например:

val list: List[Int] = ... 
list.view.filter(_ > 0).map(_ * 2) 

Как узнать, когда Scala пришло время, чтобы пройти через список в цикле и применять все фильтрации и отображения материала?

При использовании точки зрения, он будет рассчитывать значение, когда вы на самом деле идти использовать материализованное значение:

val x = list.view.filter(_ > 0).map(_ * 2) 
println(x.head * 2) 

Это относится только фильтр и карта, когда голова называются.

+2

'withFilter' не ограничивается' List'. Все 'Traversable' поддерживают его. –

+0

а как насчет groupBy, flatMap и других функций? Я полагаю, что невозможно использовать представление в этом случае из-за нового типа создаваемой коллекции. Как ты думаешь? – maks

+0

Ваша интуиция верна в отношении 'groupBy': даже если вы сначала вызываете представление в списке, используя groupBy, рассчитываете группировку с нетерпением как« Карта ». С другой стороны, 'flatMap' поддерживает вид (и его лень). –

2

Если есть map после filter, вы всегда можете с помощью collect вместо:

list.filter(0<).map(2*) 

в

list.collect{ case x if x > 0 => 2*x } 
+0

или просто использовать для понимания: 'for (e <- list; if e> 0) yield e * 2' –

Смежные вопросы