Commit a6156873 authored by David Symonds's avatar David Symonds

Add Inject function to iterable package.

Fix a couple of style mistakes.

R=r,rsc
APPROVED=r
DELTA=34  (30 added, 1 deleted, 3 changed)
OCL=27623
CL=27623
parent 3cc702ba
...@@ -16,7 +16,7 @@ type Iterable interface { ...@@ -16,7 +16,7 @@ type Iterable interface {
} }
func not(f func(interface {}) bool) (func(interface {}) bool) { func not(f func(interface {}) bool) (func(interface {}) bool) {
return func(e interface {}) bool { return !f(e) } return func(e interface {}) bool { return !f(e) }
} }
// All tests whether f is true for every element of iter. // All tests whether f is true for every element of iter.
...@@ -79,6 +79,26 @@ func Find(iter Iterable, f func(interface {}) bool) interface {} { ...@@ -79,6 +79,26 @@ func Find(iter Iterable, f func(interface {}) bool) interface {} {
return nil return nil
} }
// An injector function takes two arguments, an accumulated value and an
// element, and returns the next accumulated value. See the Inject function.
type Injector func(interface {}, interface {}) interface{};
// Inject combines the elements of iter by repeatedly calling f with an
// accumulated value and each element in order. The starting accumulated value
// is initial, and after each call the accumulated value is set to the return
// value of f. For instance, to compute a sum:
// var arr IntArray = []int{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// sum := iterable.Inject(arr, 0,
// func(ax interface {}, x interface {}) interface {} {
// return ax.(int) + x.(int) }).(int)
func Inject(iter Iterable, initial interface {}, f Injector) interface {} {
acc := initial;
for e := range iter.Iter() {
acc = f(acc, e)
}
return acc
}
// mappedIterable is a helper struct that implements Iterable, returned by Map. // mappedIterable is a helper struct that implements Iterable, returned by Map.
type mappedIterable struct { type mappedIterable struct {
it Iterable; it Iterable;
...@@ -95,7 +115,7 @@ func (m *mappedIterable) iterate(out chan<- interface {}) { ...@@ -95,7 +115,7 @@ func (m *mappedIterable) iterate(out chan<- interface {}) {
func (m *mappedIterable) Iter() <-chan interface {} { func (m *mappedIterable) Iter() <-chan interface {} {
ch := make(chan interface {}); ch := make(chan interface {});
go m.iterate(ch); go m.iterate(ch);
return ch; return ch
} }
// Map returns an Iterable that returns the result of applying f to each // Map returns an Iterable that returns the result of applying f to each
...@@ -106,9 +126,8 @@ func Map(iter Iterable, f func(interface {}) interface {}) Iterable { ...@@ -106,9 +126,8 @@ func Map(iter Iterable, f func(interface {}) interface {}) Iterable {
// Partition(iter, f) returns Filter(iter, f) and Filter(iter, !f). // Partition(iter, f) returns Filter(iter, f) and Filter(iter, !f).
func Partition(iter Iterable, f func(interface {}) bool) (Iterable, Iterable) { func Partition(iter Iterable, f func(interface {}) bool) (Iterable, Iterable) {
return Filter(iter, f), Filter(iter, not(f)) return Filter(iter, f), Filter(iter, not(f))
} }
// TODO: // TODO:
// - Inject
// - Zip // - Zip
...@@ -42,6 +42,9 @@ func doubler(n interface {}) interface {} { ...@@ -42,6 +42,9 @@ func doubler(n interface {}) interface {} {
func addOne(n interface {}) interface {} { func addOne(n interface {}) interface {} {
return n.(int) + 1 return n.(int) + 1
} }
func adder(acc interface {}, n interface {}) interface {} {
return acc.(int) + n.(int)
}
// A stream of the natural numbers: 0, 1, 2, 3, ... // A stream of the natural numbers: 0, 1, 2, 3, ...
type integerStream struct {} type integerStream struct {}
...@@ -107,6 +110,13 @@ func TestFind(t *testing.T) { ...@@ -107,6 +110,13 @@ func TestFind(t *testing.T) {
} }
} }
func TestInject(t *testing.T) {
res := Inject(oneToFive, 0, adder);
if res.(int) != 15 {
t.Errorf("Inject(oneToFive, 0, adder) = %v, want 15", res)
}
}
func TestMap(t *testing.T) { func TestMap(t *testing.T) {
res := Data(Map(Map(oneToFive, doubler), addOne)); res := Data(Map(Map(oneToFive, doubler), addOne));
assertArraysAreEqual(t, res, []int{ 3, 5, 7, 9, 11 }) assertArraysAreEqual(t, res, []int{ 3, 5, 7, 9, 11 })
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment