Browse Source

Add "unique_by"

Billy Barrow 4 tuần trước cách đây
mục cha
commit
352d100998
2 tập tin đã thay đổi với 17 bổ sung9 xóa
  1. 11 5
      src/lib/Enumerable.vala
  2. 6 4
      src/lib/Modifiers/Unique.vala

+ 11 - 5
src/lib/Enumerable.vala

@@ -255,13 +255,19 @@ namespace Invercargill {
             });
         }
 
-        public virtual Enumerable<T> distinct(owned EqualityDelegate<T> comparison) {
-            return new UniqueQuery<T>(this, (owned)comparison);
+        public virtual Enumerable<T> distinct(owned EqualityDelegate<T>? comparison = null) {
+            return distinct_by<T>(i => i, (owned)comparison);
         }
 
-        public virtual Enumerable<Grouping<TKey, T>> group_by<TKey>(TransformDelegate<T, TKey> key_selector, EqualityDelegate<TKey> key_equality) {
-            var keys = select<TKey>(i => key_selector(i)).distinct((a, b) => key_equality(a, b));
-            return keys.select<Grouping<TKey, T>>(g => new Grouping<TKey, T>(g, this.where(i => key_equality(g, key_selector(i)))));
+        public virtual Enumerable<T> distinct_by<TProp>(owned TransformDelegate<T, TProp> property_selector, owned EqualityDelegate<TProp>? property_equality) {
+            var func = property_equality ?? Operators.equality<T>();
+            return new UniqueByQuery<T, TProp>(this, (owned)property_selector, (owned)func);
+        }
+
+        public virtual Enumerable<Grouping<TKey, T>> group_by<TKey>(owned TransformDelegate<T, TKey> key_selector, owned EqualityDelegate<TKey>? key_equality = null) {
+            var equality = key_equality ?? Operators.equality<TKey>();
+            var keys = select<TKey>(i => key_selector(i)).distinct((a, b) => equality(a, b));
+            return keys.select<Grouping<TKey, T>>(g => new Grouping<TKey, T>(g, this.where(i => equality(g, key_selector(i)))));
         }
 
         public virtual Enumerable<T> @with(T item, uint times = 1) {

+ 6 - 4
src/lib/Modifiers/Unique.vala

@@ -1,11 +1,13 @@
 namespace Invercargill {
 
-    private class UniqueQuery<T> : BaseQuery<T, T> {
-        private EqualityDelegate<T> comparison;
+    private class UniqueByQuery<T, TProp> : BaseQuery<T, T> {
+        private EqualityDelegate<TProp> comparison;
+        private TransformDelegate<T, TProp> selector;
 
-        public UniqueQuery(Enumerable<T> input, owned EqualityDelegate<T> compare) {
+        public UniqueByQuery(Enumerable<T> input, owned TransformDelegate<T, TProp> selector, owned EqualityDelegate<TProp> compare) {
             this.input = input;
             comparison = (owned)compare;
+            this.selector = (owned)selector;
         }
 
         public override Tracker<T> get_tracker() {
@@ -18,7 +20,7 @@ namespace Invercargill {
                         return false;
                     }
                     var next = tracker.get_next();
-                    if(previous.any(p => comparison(p, next))) {
+                    if(previous.any(p => comparison(selector(p), selector(next)))) {
                         continue;
                     }
                     previous.add(next);