230 likes | 373 Views
Map, filter and reduce. Programming by composition. Mapping. Apply operation to each element of a list, gathering the results in a new list. Example: list: (“Your” “call” “is” “important” “to” “us”) operation: string length result: (4 4 2 9 2 2). Conceptual diagram (specific case).
E N D
Map, filter and reduce Programming by composition
Mapping • Apply operation to each element of a list, gathering the results in a new list. • Example: • list: (“Your” “call” “is” “important” “to” “us”) • operation: string length • result: (4 4 2 9 2 2)
Conceptual diagram(specific case) (“Your” “call” “is” “important” “to” “us”) String length MAP (4 4 2 9 2 2)
Conceptual diagram(generalized) Input list Unary Operation MAP Output list
Conceptual diagram(generalized) Input list Unary Operation INVARIANT MAP Output list
Conceptual diagram(generalized) Input list VARIANTS VARIANTS Unary Operation MAP Output list
Code (Map) publicclass Map<Domain, Range> implementsIAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> { publicLRStruct<Range> emptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { returnnewLRStruct<Range>(); } publicLRStruct<Range> nonEmptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { returnhost.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); } }
Code (Map)Invariant parts public class Map<Domain, Range> implementsIAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> { public LRStruct<Range> emptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); } public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); } }
Code (Map)Invariant parts public class Map<Domain, Range> implementsIAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> { public LRStruct<Range> emptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); } public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); } }
Code (Map)Invariant parts public class Map<Domain, Range> implementsIAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> { public LRStruct<Range> emptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); } public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); } } Map operation to rest of list, getting answer recursively
Code (Map)Invariant parts public class Map<Domain, Range> implementsIAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> { public LRStruct<Range> emptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); } public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); } } Apply operation to first item of list
Code (Map)Invariant parts public class Map<Domain, Range> implementsIAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> { public LRStruct<Range> emptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); } public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); } } Insert result into new list
Code (Map)Variant parts public class Map<Domain, Range> implementsIAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> { public LRStruct<Range> emptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); } public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); } } VARIANT: the input list VARIANT: the input list
Code (Map)Variant parts public class Map<Domain, Range> implementsIAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> { public LRStruct<Range> emptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); } public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host, IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); } } VARIANT: the operation VARIANT: the operation
The IUnaryOperation interface publicinterfaceIUnaryOperation<Domain, Range> { public Range apply(Domainarg); }
Mapping: Domain Rangef: xf(x) DOMAIN RANGE x f(x)
A concrete operation publicclassStringLenimplementsIUnaryOperation<String,Integer>{ public Integer apply(Stringarg) { returnarg.length(); } } DOMAIN RANGE
A concrete operation publicclass Times2 implementsIUnaryOperation<Integer,Integer> { public Integer apply(Integerarg) { return 2*arg; } public String toString() { return"x -> 2*x"; } } DOMAIN RANGE
Reduction • Combine all values of a list using (op,id) a binary operation op, with identity element id. • Example: • list: (4 4 2 9 2 2) • operation (+,0) • result: 23
The IBinaryOperation interface publicinterfaceIBinaryOperation<Domain1,Domain2,Range> { public Range apply(Domain1 arg1, Domain2 arg2); public Range identityElement(); }
Filtering • Apply a predicate to each element of a list, building a new list of those elements for which the predicate is true. • Example: • list: (“Your” “call” “is” “important” “to” “us”) • predicate: contains exactly one vowel • result: (“call” “is” “to” “us”)
The IPredicate interface publicinterfaceIBinaryOperation<Domain1,Domain2,Range> { public Range apply(Domain1 arg1, Domain2 arg2); public Range identityElement(); }