Ver Fonte

Add some functions

Billy Barrow há 6 dias atrás
pai
commit
47baa95e9a
2 ficheiros alterados com 56 adições e 1 exclusões
  1. 54 0
      src/lib/Enumerable.vala
  2. 2 1
      src/lib/Errors.vala

+ 54 - 0
src/lib/Enumerable.vala

@@ -102,6 +102,16 @@ namespace Invercargill {
             return count;
         }
 
+        public virtual ulong long_count(PredicateDelegate<T>? predicate = null) {
+            var enumerable = this;
+            if(predicate != null) {
+                enumerable = this.where(predicate);
+            }
+            ulong count = 0;
+            enumerable.iterate(i => count++);
+            return count;
+        }
+
         public virtual bool any(PredicateDelegate<T>? predicate = null) {
             var result = false;
             var p = resolve_nullable_predicate(predicate);
@@ -210,10 +220,30 @@ namespace Invercargill {
             return new Skip<T>(this, count);
         }
 
+        public virtual Enumerable<T> skip_last(int count) {
+            return Iterate.deferred<T>(() => {
+                var buffer = to_immutable_buffer();
+                return buffer.take(int.max(0, (int)buffer.length - count));
+            });
+        }
+
+        // TODO: This one could realistically be a modifier using a ring buffer so we don't have to
+        // buffer the whole sequence
+        public virtual Enumerable<T> take_last(int count) {
+            return Iterate.deferred<T>(() => {
+                var buffer = to_immutable_buffer();
+                return buffer.skip(int.max(0, (int)buffer.length - count));
+            });
+        }
+
         public virtual Enumerable<TOut> cast<TOut>() {
             return select<TOut>(i => (TOut)i);
         }
 
+        public virtual Enumerable<TOut> of_type<TOut>() {
+            return where(i => i is TOut).cast<TOut>();
+        }
+
         public virtual Enumerable<TOut> parallel_select<TOut>(owned TransformDelegate<T, TOut> transform, uint workers = 0) {
             var actual_workers = workers;
             if(actual_workers < 1) {
@@ -457,6 +487,30 @@ namespace Invercargill {
             return null;
         }
 
+        public virtual T element_at(uint index) throws SequenceError {
+            T item = null;
+            var tracker = get_tracker();
+            for(uint i = 0; i <= index; i++) {
+                if(!tracker.has_next()) {
+                    throw new SequenceError.TOO_FEW_ELEMENTS(@"The sequence contains less than $(index+1) element(s)");
+                }
+                item = tracker.get_next();
+            }
+            return item;
+        }
+
+        public virtual T? element_at_or_default(uint index) {
+            T item = null;
+            var tracker = get_tracker();
+            for(uint i = 0; i <= index; i++) {
+                if(!tracker.has_next()) {
+                    return null;
+                }
+                item = tracker.get_next();
+            }
+            return item;
+        }
+
         public virtual string to_string(StringifyDelegate<T>? stringifier = null, string seperator = "") {
             bool is_first = true;
             stringifier = stringifier ?? Operators.stringify<T>();

+ 2 - 1
src/lib/Errors.vala

@@ -13,7 +13,8 @@ namespace Invercargill {
     public errordomain SequenceError {
         NO_ELEMENTS,
         MULTUPLE_ELEMENTS,
-        INVALID_TYPE
+        INVALID_TYPE,
+        TOO_FEW_ELEMENTS,
     }
 
     public errordomain ByteCompositionReadError {