[libgee] Add Iterator.scan method



commit 06a6edb642554d881ca2fa1223e19c1aadec70fd
Author: Maciej Piechotka <uzytkownik2 gmail com>
Date:   Mon May 2 12:26:11 2011 +0100

    Add Iterator.scan method

 gee/iterator.vala         |   34 ++++++++++++++++++++++++++++++++++
 tests/testcollection.vala |   39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 0 deletions(-)
---
diff --git a/gee/iterator.vala b/gee/iterator.vala
index 11d8585..0427654 100644
--- a/gee/iterator.vala
+++ b/gee/iterator.vala
@@ -234,6 +234,40 @@ public interface Gee.Iterator<G> : Object {
 		});
 	}
 
+	/**
+	 * Creates a new iterator that is initialy pointing to seed. Then
+	 * subsequent values are obtained after applying the function to previous
+	 * value and the current item.
+	 *
+	 * The resulting iterator is always valid and it contains the seed value.
+	 *
+	 * @param f Folding function
+	 * @param seed original seed value
+	 * @return Iterator containing values of subsequent values of seed
+	 */
+	public virtual Iterator<A> scan<A> (FoldFunc<A, G> f, owned A seed) {
+		bool seed_emitted = false;
+		return stream<A>((state, item, out val) => {
+			switch (state) {
+			case Stream.YIELD:
+				if (seed_emitted) {
+					return Stream.CONTINUE;
+				} else {
+					val = new Lazy<A>.from_value (seed);
+					seed_emitted = true;
+					return Stream.YIELD;
+				}
+			case Stream.CONTINUE:
+				val = new Lazy<A> (() => {seed = f ((owned)item, (owned) seed); return seed;});
+				return Stream.YIELD;
+			case Stream.END:
+				return Stream.END;
+			default:
+				assert_not_reached ();
+			}
+		});
+	}
+
 	public enum Stream {
 		YIELD,
 		CONTINUE,
diff --git a/tests/testcollection.vala b/tests/testcollection.vala
index 3e86984..246b94b 100644
--- a/tests/testcollection.vala
+++ b/tests/testcollection.vala
@@ -48,6 +48,7 @@ public abstract class CollectionTests : Gee.TestCase {
 		add_test ("[Collection] fold", test_fold);
 		add_test ("[Collection] foreach", test_foreach);
 		add_test ("[Collection] map", test_map);
+		add_test ("[Collection] scan", test_scan);
 	}
 
 	protected Collection<string> test_collection;
@@ -824,5 +825,43 @@ public abstract class CollectionTests : Gee.TestCase {
 		assert (two);
 		assert (three);
 	}
+
+	public void test_scan () {
+		assert (test_collection.add ("one"));
+		assert (test_collection.add ("two"));
+		assert (test_collection.add ("three"));
+
+		bool one = false;
+		bool two = false;
+		bool three = false;
+
+		var iter = test_collection.iterator().scan<int> ((str, cur) => {
+			if (str == "one") {
+				assert (!one);
+				one = true;
+			} else if (str == "two") {
+				assert (!two);
+				two = true;
+			} else if (str == "three") {
+				assert (!three);
+				three = true;
+			} else {
+				assert_not_reached ();
+			}
+			return cur + 1;
+		}, 0);
+
+		int j = 0;
+		do {
+			assert (j == iter.get ());
+			assert (j == iter.get ());
+			j++;
+		} while (iter.next ());
+
+		assert (j == test_collection.size + 1);
+		assert (one);
+		assert (two);
+		assert (three);
+	}
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]