SC functional programming
R26: map, filter, reduce¶
problems: write a method that finds all the words in the Java files in your project.
Approach 0:
Use recursion.
1 | /** |
Goal: design functions that operate over sequences of elements.
Approach 1: abstracting out control flow
Ex 1: Iterator abstraction
Without worrying about the data representations.
1 | for (int ii = 0; ii < files.size(); ii++) { |
1 | Iterator<File> iter = files.iterator(); |
Ex 2: map/filter/reduce abstraction
use streams to represent the entire sequence of elements.(java,cpp都有stream的datatype)
- map : Stream<E> × (E → F) → Stream<F>
Approach 1.1 higher order functions: pass function in functions.
Java related: call chaining, method reference.
1 | List.of(1, 4, 9, 16).stream() |
1 | List.of(1, 4, 9, 16).stream() |
1 | Function<Double,Double> mySquareRoot = Math::sqrt; |
-
filter : Stream<E> × (E → boolean) → Stream<E>
-
reduce : Stream<E> × E × (E × E → E) → E
Three design choices in the reduce operation.
-
whether to require an initial value
1
2
3
4
5
6
7List.of(1,2,3).stream()
.reduce(0, (x,y) -> x+y)
// computes (((0+1)+2)+3) to produce the integer 6
List.of(5, 8, 3, 1).stream()
.reduce(Math::max)
// computes max(max(max(5,8),3),1) and returns an Optional<Integer> value containing 8 -
the order in which the elements are accumulated.
- Depends on the associativity. If non-associative, the order of combination changes.
-
reduction to another type
in java: reduce : Stream<E> × F × (F × E → F) × (F × F → F) → F
- an accumulator ⊙ : F × E → F that adds an element from the sequence (of type E) into the growing result (of type F)
- a combiner ⊗ : F × F → F that combines two partial results, each accumulated from part of the sequence, into a growing result
-