[libgee] Add some more query operations for Traversable<G>
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgee] Add some more query operations for Traversable<G>
- Date: Sun, 29 Jan 2017 21:18:40 +0000 (UTC)
commit ed30714507e6099c5f56bd7469706e550a68bda8
Author: Rodrigo Moya <rodrigo gnome org>
Date: Thu Dec 29 01:05:00 2016 +0100
Add some more query operations for Traversable<G>
* first_match (Predicate<G>) returns the first item that matches
* any_match (Predicate<G>) checks if any element matches
* all_match (Predicate<G>) checks if all elements match
* max/min returns max/min value
* order_by to perform ordering on any Traversable
https://bugzilla.gnome.org/show_bug.cgi?id=776558
gee/traversable.vala | 112 +++++++++++++++++++++++++++++++++++++++++++++
tests/testcollection.vala | 62 +++++++++++++++++++++++++
2 files changed, 174 insertions(+), 0 deletions(-)
---
diff --git a/gee/traversable.vala b/gee/traversable.vala
index 77ce6ea..bc6ae1d 100644
--- a/gee/traversable.vala
+++ b/gee/traversable.vala
@@ -446,6 +446,118 @@ public interface Gee.Traversable<G> : Object {
}
}
+ /**
+ * Returns the first element that matches a given condition
+ *
+ * @param pred Predicate to be called to check for matches
+ * @return The first element that matches or null
+ * @since 0.18.2
+ */
+ [CCode (ordering = 10)]
+ public virtual G? first_match (owned Predicate<G> pred) {
+ G? result = null;
+ this.foreach ((item) => {
+ if (pred (item)) {
+ result = item;
+ return false;
+ }
+ return true;
+ });
+ return (owned) result;
+ }
+
+ /**
+ * Returns whether any element matches the given predicate.
+ *
+ * This is similar to @first_match, with the difference that it
+ * just returns whether there is a match or not, not the value
+ * of the match.
+ *
+ * @param pred Predicate to be called to check for matches
+ * @return Whether there was a match or not
+ * @since 0.18.2
+ */
+ [CCode (ordering = 11)]
+ public virtual bool any_match (owned Predicate<G> pred) {
+ return this.first_match (pred) != null;
+ }
+
+ /**
+ * Checks whether all elements match the given predicate.
+ *
+ * @param pred Predicate to be called to check for matches
+ * @return Whether all elements match or not
+ * @since 0.18.2
+ */
+ [CCode (ordering = 12)]
+ public virtual bool all_match (owned Predicate<G> pred) {
+ bool result = true;
+ this.foreach ((item) => {
+ if (!pred (item)) {
+ result = false;
+ return false;
+ }
+ return true;
+ });
+ return result;
+ }
+
+ /**
+ * Returns the item in the sequence that contains the max value
+ * based on the given compare function.
+ *
+ * @param compare Function to be called for comparisons
+ * @return The item containing the max value.
+ * @since 0.18.2
+ */
+ [CCode (ordering = 13)]
+ public virtual G max (owned CompareDataFunc<G> compare) {
+ G max_value = null;
+ this.foreach ((item) => {
+ if (max_value == null || compare (max_value, item) > 0) {
+ max_value = item;
+ }
+ return true;
+ });
+ return max_value;
+ }
+
+ /**
+ * Returns the item in the sequence that contains the min value
+ * based on the given compare function.
+ *
+ * @param compare Function to be called for comparisons
+ * @return The item containing the min value.
+ * @since 0.18.2
+ */
+ [CCode (ordering = 14)]
+ public virtual G min (owned CompareDataFunc<G> compare) {
+ G min_value = null;
+ this.foreach ((item) => {
+ if (min_value == null || compare (min_value, item) < 0) {
+ min_value = item;
+ }
+ return true;
+ });
+ return min_value;
+ }
+
+ /**
+ * Returns a new iterator containing the elements in the source
+ * ordered as specified by the comparison function.
+ *
+ * @param compare Comparison function
+ * @return A new iterator with the source elements sorted.
+ * @since 0.18.2
+ */
+ [CCode (ordering = 15)]
+ public virtual Iterator<G> order_by (owned CompareDataFunc<G>? compare = null) {
+ ArrayList<G> result = new ArrayList<G> ();
+ this.foreach ((item) => result.add (item));
+ result.sort (compare);
+ return result.iterator ();
+ }
+
public enum Stream {
YIELD,
CONTINUE,
diff --git a/tests/testcollection.vala b/tests/testcollection.vala
index 268724a..819e130 100644
--- a/tests/testcollection.vala
+++ b/tests/testcollection.vala
@@ -51,6 +51,11 @@ public abstract class CollectionTests : Gee.TestCase {
add_test ("[Collection] scan", test_scan);
add_test ("[Collection] filter", test_filter);
add_test ("[Collection] chop", test_chop);
+ add_test ("[Collection] first_match", test_first_match);
+ add_test ("[Collection] any_match", test_any_match);
+ add_test ("[Collection] all_match", test_all_match);
+ add_test ("[Collection] max_min", test_max_min);
+ add_test ("[Collection] order_by", test_order_by);
}
protected Collection<string> test_collection;
@@ -1197,5 +1202,62 @@ public abstract class CollectionTests : Gee.TestCase {
assert (!iter.next ());
assert (iter2.next ());
}
+
+ public void test_first_match () {
+ assert (test_collection.add ("one"));
+ assert (test_collection.add ("two"));
+ assert (test_collection.add ("three"));
+
+ assert (test_collection.first_match ((x) => x == "one") == "one");
+ assert (test_collection.first_match ((x) => x == "two") == "two");
+ assert (test_collection.first_match ((x) => x == "three") == "three");
+ assert (test_collection.first_match ((x) => x == "four") == null);
+ }
+
+ public void test_any_match () {
+ assert (test_collection.add ("one"));
+ assert (test_collection.add ("two"));
+ assert (test_collection.add ("three"));
+
+ assert (test_collection.any_match ((x) => x == "one"));
+ assert (test_collection.any_match ((x) => x == "two"));
+ assert (test_collection.any_match ((x) => x == "three"));
+ assert (!test_collection.any_match ((x) => x == "four"));
+ }
+
+ public void test_all_match () {
+ assert (test_collection.add ("one"));
+ assert (test_collection.all_match ((x) => x == "one"));
+
+ assert (test_collection.add ("two"));
+ assert (!test_collection.all_match ((x) => x == "one"));
+ }
+
+ public void test_max_min () {
+ assert (test_collection.add ("one"));
+ assert (test_collection.add ("two"));
+ assert (test_collection.add ("three"));
+
+ assert (test_collection.max ((a, b) => strcmp (a, b)) == "one");
+ assert (test_collection.min ((a, b) => strcmp (a, b)) == "two");
+ }
+
+ public void test_order_by () {
+ assert (test_collection.add ("one"));
+ assert (test_collection.add ("two"));
+ assert (test_collection.add ("three"));
+
+ var sorted_collection = test_collection.order_by ((a, b) => strcmp (a, b));
+
+ string previous_item = null;
+ while (sorted_collection.next ()) {
+ var item = sorted_collection.get ();
+ if (previous_item != null) {
+ assert (strcmp (previous_item, item) <= 0);
+ }
+
+ previous_item = item;
+ }
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]